17
6.0.0.4
false
2013-04-29T18:21:21+02:00
JHP
2021-09-13T12:10:34
Lech9082
ebd
FootnoteCitationKey
General, History
de
Universität Oldenburg Institut für Geschichte v2021-09-13
AddLetterAfterYear
Full
Full
All
LastNameFirstName
Year
false
Always
1
2
3
JournalArticle
false
{0}
Always
Always
.
Reference
true
Abstract
false
false
_(acc. {0})
Always
Always
Reference
true
NextElementHasData
(
NextElementHasData
acc.
AccessDate
false
d.M.yyyy
Always
in press
false
true
PreviousElementHasData
)
false
{0}
Always
Always
.
Reference
true
Additions
false
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0}
Always
Always
:
Reference
true
Authors
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "Ders.";
break;
case PersonEquality.N:
text = "Dass.";
break;
default: //all others
text = "Dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0}
Always
Always
.
Reference
true
AuthorsOrEditorsOrOrganizations
false
-1
LastNameFirstName
Full
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
Option1
true
false
false
None
false
{0} [superscript]
Always
Always
Reference
true
IndexInBibliography
false
Always
Arabic
false
false
false
false
false
false
false
true
false
Always
Always
LetterLowerCase
false
false
false
false
false
false
false
true
false
Always
Always
false
{0}
Always
Always
.
Reference
true
Categories
false
false
{0}
Always
Always
.
Reference
true
Collaborators
false
-1
LastNameFirstName
Full
Full
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
Reference
true
Evaluation
false
false
{0}
Always
Always
.
Reference
true
CreatedBy
false
false
vom {0}
Always
Always
Reference
true
NextElementHasData
vom
Date
false
dd.MM.yyyy
Always
im Druck
true
true
false
{0}
Always
Always
.
Reference
true
Date2
false
D
Always
im Druck
true
false
false
, {0}
Always
Always
,
Reference
true
Edition
false
Always
th
Always
Always
. Aufl.
Always
Always
. Aufl.
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0} (eds.)
Always
Always
.
Reference
true
Editors
false
1
LastNameFirstNameCompact
Full
Full
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
FirstNameLastName
Full
Full
All
Always
,
Always
,
Always
and
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
true
Always
and
false
3
1
Always
, et al.
false
false
false
false
Always
,
Always
(ed.)
Always
(eds.)
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
Reference
true
FirstFootnoteCitationNumber
false
false
false
false
{0}
Always
Always
.
Reference
true
CustomField1
false
false
{0}
Always
Always
.
Reference
true
CustomField2
false
false
{0}
Always
Always
.
Reference
true
CustomField3
false
false
{0}
Always
Always
.
Reference
true
CustomField4
false
false
. {0}
Always
Always
.
Reference
true
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
Reference
true
Isbn
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
, in: {0}
Always
Always
,
Reference
true
NextElementHasData
in:
Periodical
false
true
Name
false
{0}
Always
Always
.
Reference
true
Keywords
false
false
{0}
Always
Always
.
Reference
true
Language
false
false
{0}
Always
Always
.
Reference
true
ModifiedBy
false
false
{0}
Always
Always
.
Reference
true
Locations
false
false
{0}
Always
Always
.
Reference
true
Notes
false
false
{0}
Always
Always
Reference
true
Number
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
.
Reference
true
PageCount
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
,
Reference
true
NumberOfVolumes
false
Always
th
Always
Always
Bde
Always
Always
Bd.
Always
1|st|2|nd|3|rd
Always
Always
false
false
, {0}
Always
Always
,
Reference
true
OnlineAddress
false
false
false
false
false
false
{0}
Always
Always
.
Reference
true
OriginalCheckedBy
false
false
{0}
Always
Always
.
Reference
true
OriginalPublication
false
D
Always
im Druck
true
false
false
{0}
Always
Always
.
Reference
true
OthersInvolved
false
-1
LastNameFirstName
Abbreviated
Abbreviated
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
, S. {0}
Always
Always
,
Reference
true
PageRange
false
Arabic
true
FullRange
Always
Sp.
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
S.
Always
–
Always
false
StartPageOnly
Always
S.
Always
Always
false
FullRange
Always
S.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
.
Reference
true
ParallelTitle
false
false
, {0}
Always
Always
,
Reference
true
PlaceOfPublication
false
true
3
1
Always
u.a.
Always
/
false
{0}
Always
Always
.
Reference
true
Price
false
false
: {0}
Always
Always
:
Reference
true
Publishers
false
false
, S. {0}
Always
Always
,
Reference
true
QuotationPageRange
false
Arabic
true
FullRange
Always
Sp.
Always
–
Always
false
StartPageOnly
Always
Always
Always
true
StartPageOnly
Always
Always
Always
f.
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
S.
Always
–
Always
false
StartPageOnly
Always
S.
Always
Always
true
StartPageOnly
Always
S.
Always
Always
f.
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
.
Reference
true
TextLinks
false
false
_({0} {1})
Always
Always
Reference
true
AnyElementInComponentHasData
(
SeriesTitle
false
true
Name
NextElementHasData
Volume
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
AnyElementInComponentHasData
)
false
{0}
Always
Always
.
Reference
true
SeriesTitleEditors
false
-1
LastNameFirstName
Full
Full
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
Reference
true
ShortTitle
false
false
, {0}
Always
Always
,
Reference
true
SpecificField1
false
false
, {0}
Always
Always
,
Reference
true
SpecificField2
false
false
{0}
Always
Always
.
Reference
true
SpecificField3
false
false
{0}
Always
Always
.
Reference
true
SpecificField4
false
false
{0}
Always
Always
.
Reference
true
SpecificField5
false
false
{0}
Always
Always
.
Reference
true
SpecificField6
false
false
{0}
Always
Always
.
Reference
true
SpecificField7
false
false
{0}
Always
Always
.
Reference
true
StorageMedium
false
false
{0}
Always
Always
.
Reference
true
Tasks
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
: {0} [recte]
Always
Always
:
Reference
true
Title
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
. {0} [recte]
Always
Always
.
Reference
true
Subtitle
false
false
{0}
Always
Always
.
Reference
true
TitleInOtherLanguages
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
. {0}
Always
Always
.
Reference
true
TitleSupplement
false
false
{0}
Always
Always
.
Reference
true
TableOfContents
false
false
, {0} [recte]
Always
Always
,
Reference
true
CitationKey
false
false
false
{0}
Always
Always
.
Reference
true
TranslatedTitle
false
false
{0}
Always
Always
.
Reference
true
UniformTitle
false
false
, {0}
Always
Always
,
Reference
true
Volume
false
Always
th
Always
Bd.
Always
Always
Bd.
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
_({0})
Always
Always
Reference
true
NextElementHasData
(
YearResolved
false
yyyy
Always
im Druck
false
true
PreviousElementHasData
)
false
(
Always
Always
Reference
true
Always
(
false
)
Always
Always
Reference
true
Always
)
false
[
Always
Always
Reference
true
Always
[
false
]
Always
Always
Reference
true
Always
]
false
, {0}
Always
Always
,
Reference
true
YearResolved
false
dd.MM.yyyy
Always
in press
false
true
false
{0} [last name]
Always
Always
Reference
true
AuthorsOrEditorsOrOrganizations
false
-1
LastNameOnly
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
Option1
true
false
false
Standard
false
({0})
Always
Always
Reference
true
NextElementHasData
(
Number
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
PreviousElementHasData
)
false
, pp. {0}
Always
Always
,
Reference
true
PageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
pp.
Always
–
Always
true
StartPageOnly
Always
p.
Always
Always
false
FullRange
Always
pp.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
_{0}
Always
Always
Reference
true
YearResolved
false
yyyy
Always
(im Druck)
false
true
false
, {0} edn.
Always
Always
,
Reference
true
EditionNumberResolved
false
Always
th
Always
Always
edn.
Always
Always
edn.
Always
1|st|2|nd|3|rd
Always
Always
true
false
. {0} [italic]
Always
Always
.
Reference
true
Title
false
false
false
false
true
false
false
false
false
false
false
: {0} [italic]
Always
Always
:
Reference
true
Subtitle
false
false
false
false
true
false
false
false
false
false
false
, »{0}. {1}«
Always
Always
,
Reference
true
AnyElementInComponentHasData
»
Title
false
PreviousAndNextElementsHaveData
.
Subtitle
false
AnyElementInComponentHasData
«
false
. {0}
Always
Always
.
Reference
true
Doi
false
false
{0}
Always
Always
.
Reference
true
CustomField5
false
false
{0}
Always
Always
.
Reference
true
CustomField6
false
false
{0}
Always
Always
.
Reference
true
CustomField7
false
false
{0}
Always
Always
.
Reference
true
CustomField8
false
false
{0}
Always
Always
.
Reference
true
CustomField9
false
false
{0} ed.
Always
Always
.
Reference
true
Edition
false
Always
th
Always
Always
ed.
Always
Always
ed.
Always
1|st|2|nd|3|rd
Always
Always
true
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0} (Hg.)
Always
Always
.
Reference
true
Editors
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
, {0}
Always
Always
,
Reference
true
Date
false
dd.MM.yyyy
Always
in press
false
true
false
{0}
Always
Always
.
Reference
true
Subtitle
false
false
, {0}
Always
Always
,
Reference
true
Volume
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
. {0}
Always
Always
.
Reference
true
YearResolved
false
yyy
Always
in press
true
true
false
. {0} [italic]
Always
Always
.
Reference
true
Periodical
false
true
false
false
false
true
false
false
false
false
false
Name
false
{0}
Always
Always
.
Reference
true
IndexInBibliography
false
Always
Arabic
Always
Always
LetterLowerCase
Always
Always
false
, pp. {0}
Always
Always
,
Reference
true
QuotationPageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
pp.
Always
–
Always
true
StartPageOnly
Always
p.
Always
Always
false
FullRange
Always
pp.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
ebd.
Always
Always
.
Reference
true
Always
ebd.
false
{0}
Always
/
Always
Reference
true
Volume
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
, S. {0}
Always
Always
,
Reference
true
PageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
S.
Always
–
Always
false
StartPageOnly
Always
S.
Always
Always
false
FullRange
Always
S.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
, {0}
Always
Always
,
Reference
true
Title
false
false
{0} [abbr]
Always
Always
.
Reference
true
AuthorsOrEditorsOrOrganizations
false
-1
FirstNameLastName
Abbreviated
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0} [All caps]
Always
Always
Reference
true
Title
false
true
false
false
false
false
false
false
false
false
false
({0} {1}, R: {2})
Always
Always
Reference
true
AnyElementInComponentHasData
(
PlaceOfPublication
false
false
-1
-1
Always
, et al.
Always
,
PreviousAndNextElementsHaveData
YearResolved
false
yyyy
Always
In press
true
true
NextElementHasData
, R:
Authors
false
-1
FirstNameLastName
Full
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
AnyElementInComponentHasData
)
false
{0} [abbr]
Always
Always
.
Reference
true
Authors
false
-1
FirstNameLastName
Abbreviated
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0} (Hg.) [abbr]
Always
Always
.
Reference
true
Editors
false
-1
FirstNameLastName
Abbreviated
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
3
Always
et al.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
, hier S. {0}
Always
Always
,
Reference
true
NextElementHasData
hier
QuotationPageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
S.
Always
–
Always
false
StartPageOnly
Always
S.
Always
Always
false
FullRange
Always
S.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
Siehe {0}
Always
Always
Reference
true
NextElementHasData
Siehe
OnlineAddress
false
false
false
false
false
false
{0} [footnote]
Always
Always
.
Reference
true
AuthorsOrEditorsOrOrganizations
false
-1
FirstNameLastName
Full
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0} (Hg.) [footnote]
Always
Always
.
Reference
true
Editors
false
-1
FirstNameLastName
Full
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
3
Always
et al.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0} [footnote]
Always
Always
.
Reference
true
Authors
false
-1
FirstNameLastName
Full
Abbreviated
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
—
Always
Always
.
Reference
true
Always
—
false
: {0}
Always
Always
:
Reference
true
QuotationPageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
,
Reference
true
Periodical
false
true
Name
false
, {0} [italic]
Always
Always
,
Reference
true
CitationKey
false
false
false
false
true
false
false
false
false
false
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
handled = false;
//ComponentPartFilter - SuppressURIParts V1.0.cs
//Version 1.1 Added option for making path wrappable (injection of zero-width breaking opportunity characters after each '/'
//EXAMPLE
//http://www.url.de/path1/path2/path3/page.html
var suppressHTTP = true; //true: www.url.de/path1/path2/path3/page.html
var suppressWWW = true; //true: url.de/path1/path2/path3/page.html
var suppressPath = true; //true: url.de
var makePathWrappable = true; //replaced '/' by '/' plus zero-width breaking opportunity
if (componentPart == null) return null;
if (citation == null || citation.Reference == null) return null;
var onlineAddress = citation.Reference.OnlineAddress;
if (string.IsNullOrEmpty(onlineAddress)) return null;
var onlineAddressFieldElement = componentPart.GetFieldElements().FirstOrDefault(fieldElement => fieldElement.PropertyId == ReferencePropertyId.OnlineAddress);
if (onlineAddressFieldElement == null) return null;
var onlineAddressUri = new Uri(onlineAddress);
if (onlineAddressUri == null) return null;
var scheme = onlineAddressUri.Scheme; //EXAMPLE: http
var path = onlineAddressUri.PathAndQuery; //EXAMPLE: /path1/path2/path3/page.html
var host = onlineAddressUri.Host; //EXAMPLE: www.url.de
var hostWithoutWWW = string.Empty;
var hostParts = onlineAddressUri.Host.Split('.');
if (hostParts.Count() > 0 && hostParts[0].Equals("www", StringComparison.OrdinalIgnoreCase))
{
hostWithoutWWW = String.Join(".", hostParts.Where((x, index) => index > 0)); //EXAMPLE: url.de
}
else if (hostParts.Count() > 0)
{
hostWithoutWWW = String.Join(".", hostParts);
}
if (makePathWrappable) path = path.Replace("/", "/" + ((char)8203).ToString()); //http://en.wikipedia.org/wiki/Zero-width_space \u200B' or ALT+08203
if (suppressHTTP) scheme = string.Empty;
if (!string.IsNullOrEmpty(scheme)) scheme = scheme + "://";
if (suppressWWW) host = hostWithoutWWW;
if (suppressPath) path = string.Empty;
var result = scheme + host + path;
if (string.IsNullOrEmpty(result)) return null;
var hostNameLiteralElement = new LiteralElement(componentPart, result);
componentPart.Elements.ReplaceItem(onlineAddressFieldElement, hostNameLiteralElement);
//all literal elements should always be output:
foreach(LiteralElement literalElement in componentPart.Elements.OfType())
{
literalElement.ApplyCondition = ElementApplyCondition.Always;
}
return null;
}
}
}]]>
true
In: {0} [Domain]
Always
Always
.
Reference
true
NextElementHasData
In:
OnlineAddress
false
false
false
false
false
false
H. {0}
Always
Always
,
Reference
true
Number
false
Always
th
Always
H.
Always
Always
H.
Always
Always
1|st|2|nd|3|rd
Always
H.
Always
false
false
in: {0}
Always
Always
,
Reference
true
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
Always
in:
Always
in:
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0} [first name last name]
Always
Always
,
Reference
true
Authors
false
-1
FirstNameLastName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u.a.
false
false
false
false
Always
,
Always
Regie:
Always
Regie:
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
, in: {0}
Always
Always
,
Reference
true
NextElementHasData
in:
SeriesTitle
false
true
Name
false
, hier {0}
Always
Always
,
Reference
true
NextElementHasData
hier
QuotationPageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
S.
Always
Always
false
FullRange
Always
S.
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
Reference
true
Doi
false
false
Punkt am Ende
Always
Always
Reference
true
Always
.
false
, {0} Nr.
Always
Always
,
Reference
true
Number
false
Always
th
Always
Bd.
Always
Always
Bd.
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
Reference
true
Title
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
, {0}
Always
Always
,
Reference
true
TitleSupplement
false
false
, {0}
Always
Always
,
Reference
true
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
Reference
true
PlaceOfPublication
false
true
3
1
Always
u.a.
Always
/
false
, hg. v. {0} [Vorname Nachname]
Always
Always
,
Reference
true
Editors
false
-1
FirstNameLastName
Full
Full
All
Always
,
Always
und
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u.a.
false
false
false
false
Always
,
Always
hg. v.
Always
hg. v.
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
ders.
Always
dies.
Always
dass.
Always
dies.
Always
dies.
Always
dies.
Always
dies.
Always
dies.
Always
dies.
Always
dies.
true
true
true
false
false
true
true
None
false
false
Standard
false
{0}
Always
Always
.
Reference
true
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
, {0}
Always
Always
, Zugriff:
Reference
true
AccessDate
false
dd.MM.yyyy
Always
in press
false
true
false
, {0}
Always
Always
,
Reference
true
Date2
false
dd.MM.yyyy
Always
im Druck
false
true
false
_{0}
Always
Always
Reference
true
Number
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
[Leer]
Always
Always
Reference
true
Always
false
: {0}
Always
Always
:
Reference
true
ShortTitle
false
false
, DOI:
Always
:
Always
Reference
true
Always
, DOI:
false
[Leer] {0}
Always
Always
,
Reference
true
Number
false
Always
th
Always
Heft
Always
Always
Heft
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
, in: {0}
Always
Always
Reference
true
NextElementHasData
, in:
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameOnly
Always
AttributeHasData
Always
AttributeHasData
Always
AttributeHasData
Always
AttributeHasData
false
false
{0} [last name/opt1]
Always
Always
Reference
true
AuthorsOrEditorsOrOrganizations
false
-1
LastNameOnly
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0} [last name/opt1]
Always
Always
Reference
true
Authors
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0} [last name]
Always
Always
Reference
true
Authors
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
Option1
true
false
false
Standard
false
{0} (Übers.)
Always
Always
.
Reference
true
Collaborators
false
-1
LastNameFirstName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Übers.)
Always
(Übers.)
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
{0}
Always
Always
.
Reference
true
Translators
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
Always
AttributeHasData
Always
AttributeHasData
Always
(
AttributeHasData
Always
)
AttributeHasData
false
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0} (Hg.) [last name/opt 1]
Always
Always
.
Reference
true
Editors
false
-1
LastNameOnly
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
: {0} [recte]
Always
Always
:
Reference
true
CitationKey
false
false
false
[3] Ders.)
// A group of several males is now "iid." instead of "eid."
//Version 1.6 GetPreviousVisibleCitation() method gets first previous citation where nobib = false or bibonly = false,
// Deactivate filter with /opt1 (see variable: deactivateFilterWithOption1Switch)
//Version 1.5 New variable "outputInItalics": output can quickly be changed between font style italics and neutral
//Version 1.4 New variable "deactivateFilterInsideMultipleCitations": inside multiple citations, filter can be switched off to allow for cite collapsing (see below)
//Version 1.3 Footnote index difference must not be > 0
//Version 1.2 Takes all combinations of number/sex into account
//Version 1.1 Takes organizations into account
#endregion Version History
public IEnumerable GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//if the following is set to true a placeholder citation's output will not show ders./dies. although this would normally be the case
//as e.g. the second one of the following two: {Meier 2010 #2} and {Meier 2010 #2:17-19 /opt1}
var deactivateFilterWithOption1Switch = true; //default: true
//if the following is set to true, the citation collapsing can take place (if the style is set to omit author names)
//true: (Mueller 2010, S. 10; 2011, S. 12f.; 2012, S. 17)o
//false: (Mueller 2010, S. 10; ders. 2011, S. 12 f; ders. 2012, S. 17)
var deactivateFilterInsideMultipleCitations = true; //default: true
var deactivateFilterForFirstInsideMultipleCitations = true; //default: true; only applicable when deactivateFilterInsideMultipleCitations = false
var deactivateFilterForFirstAfterMultipleCitations = true; //default: true
var deactivateFilterInIbidemIdemSequence = false; //default: false
var deactivateFilterAcrossFootnotes = false; //default: false
var deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo = true; //default: true; only applicable when deactivateFilterAcrossFootnotes = false
var deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair = true; //default: true; ditto
var outputInItalics = false; //default: true
var outputInSmallCaps = false; //default: false
var outputInBold = false; //default: false
var outputUnderlined = false; //default: false
var missingPersonsInfo = ""; //can be set to e.g. "o.A."/"ohne Autor"; leave empty otherwise
var outputMissingPersonsInfoInItalics = false; //default: false
var outputMissingPersonsInfoInSmallCaps = false; //default: false
var outputMissingPersonsInfoInBold = false; //default: false
var outputMissingPersonsInfoUnderlined = false; //default: false
var showGroupPrefixIfPresent = false; //default: false
var showGroupSuffixIfPresent = true; //default: true
handled = false;
var thisCitationIsPartOfMultipleCitation = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
PersonFieldElement personFieldElement = componentPart.Elements.OfType().FirstOrDefault();
if (personFieldElement == null) return null;
//determine current persons to compare
List thesePersons = GetPersonsDisplayed(personFieldElement, citation.Reference);
bool usePlural = thesePersons.Count() > 1;
PlaceholderCitation thisPlaceholderCitation = citation as PlaceholderCitation;
#region deactivateFilterWithOption1Switch
//SPECIAL: if this citation has the /opt1 switch set, this filter should be deactivated
if (deactivateFilterWithOption1Switch && thisPlaceholderCitation != null && thisPlaceholderCitation.FormatOption1)
{
return null;
}
#endregion deactivateFilterWithOption1Switch
//handle missing persons
#region MissingPersonsOutput
var text = string.Empty;
var output = new TextUnitCollection();
//SwissAcademic.Drawing.FontStyle fontStyle = outputInItalics ? SwissAcademic.Drawing.FontStyle.Italic : SwissAcademic.Drawing.FontStyle.Neutral;
SwissAcademic.Drawing.FontStyle fontStyle;
var personsMissing = (thesePersons == null || thesePersons.Count == 0);
var outputMissingPersonsInfo = personsMissing && !string.IsNullOrEmpty(missingPersonsInfo);
if (personsMissing && outputMissingPersonsInfo)
{
text = missingPersonsInfo;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputMissingPersonsInfoInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputMissingPersonsInfoInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputMissingPersonsInfoInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputMissingPersonsInfoUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
output.Add(new LiteralTextUnit(text, fontStyle));
handled = true;
return output;
}
else if (personsMissing)
{
return null;
}
#endregion MissingPersonsOutput
var previousVisibleCitation = GetPreviousVisibleCitation(citation);
if (previousVisibleCitation == null) return null;
if (previousVisibleCitation.Reference == null) return null;
var secondPreviousVisibleCitation = GetPreviousVisibleCitation(previousVisibleCitation);
#region MultipleCitation
if (thisPlaceholderCitation != null)
{
var printingEntries = thisPlaceholderCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries == null) return null;
if (printingEntries.Count() > 1)
{
thisCitationIsPartOfMultipleCitation = true;
}
if (thisCitationIsPartOfMultipleCitation)
{
if (deactivateFilterInsideMultipleCitations)
{
//We switch off "ders./dies." completely ... or ...
return null;
}
else
{
//... at least for the very first printing entry in a multiple citation
var index = printingEntries.IndexOf(thisPlaceholderCitation.Entry);
if (index != null && index == 0 && deactivateFilterForFirstInsideMultipleCitations) return null;
}
}
}
#endregion MultipleCitation
#region deactivateFilterInIbidemIdemSequence
//avoiding a sequence such as e.g.: [2] Ebd. -> [3] Ders.
if (deactivateFilterInIbidemIdemSequence)
{
if (secondPreviousVisibleCitation != null && secondPreviousVisibleCitation.Reference != null)
{
if (previousVisibleCitation.Reference == secondPreviousVisibleCitation.Reference) return null;
}
}
#endregion deactivateFilterInIbidemIdemSequence
#region FootnoteCitation
var thisFootnoteCitation = citation as FootnoteCitation;
if (thisFootnoteCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleFootnoteCitation = previousVisibleCitation as FootnoteCitation;
if (previousVisibleFootnoteCitation == null) return null;
var printingEntries = previousVisibleFootnoteCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleFootnoteCitation IS part of a multiple citation
return null;
}
int thisFootnoteIndex = thisFootnoteCitation.FootnoteIndex;
int previousFootnoteIndex = previousVisibleFootnoteCitation.FootnoteIndex;
var secondPreviousVisibleFootnoteCitation = secondPreviousVisibleCitation as FootnoteCitation;
int secondPreviousFootnoteIndex = secondPreviousVisibleFootnoteCitation == null ? 0 : secondPreviousVisibleFootnoteCitation.FootnoteIndex;
#region deactivateFilterAcrossFootnotes
//enforce distance rules as given by user settings above
if
(
(
deactivateFilterAcrossFootnotes &&
thisFootnoteIndex != previousFootnoteIndex
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfSeparatedByMoreThanOneIndexNo &&
thisFootnoteIndex - previousFootnoteIndex > 1
) ||
(
!deactivateFilterAcrossFootnotes &&
deactivateFilterAcrossFootnotesIfPreviousCitationNotSolitair &&
thisFootnoteIndex - previousFootnoteIndex == 1 &&
secondPreviousFootnoteIndex == previousFootnoteIndex
)
)
{
return null;
}
#endregion deactivateFilterAcrossFootnotes
}
#endregion FootnoteCitation
#region InTextCitation
var thisInTextCitation = citation as InTextCitation;
//if this citations predecessor is part of a multiple citation, but THIS is NOT, switch off filter
if (thisInTextCitation != null && !thisCitationIsPartOfMultipleCitation)
{
var previousVisibleInTextCitation = previousVisibleCitation as InTextCitation;
if (previousVisibleInTextCitation == null) return null;
var printingEntries = previousVisibleInTextCitation.Entry.Placeholder.GetPrintingEntries();
if (printingEntries != null && printingEntries.Count() > 1 && deactivateFilterForFirstAfterMultipleCitations)
{
//previousVisibleInTextCitation IS part of a multiple citation
return null;
}
}
#endregion InTextCitation
//determine previous persons
List previousPersons = GetPersonsDisplayed(previousVisibleCitation);
if (previousPersons == null || previousPersons.Count == 0) return null;
var equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
#region Equality detected - generate output
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
switch (equality)
{
case PersonEquality.M:
text = "ders.";
break;
case PersonEquality.N:
text = "dass.";
break;
default: //all others
text = "dies.";
break;
}
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
#region GroupPrefix
if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixPlural.Text, personFieldElement.GroupPrefixPlural.FontStyle));
}
else if (showGroupPrefixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupPrefixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupPrefixSingular.Text, personFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
output.Add(new LiteralTextUnit(text, fontStyle));
#region GroupSuffix
if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixPlural.Text) && usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixPlural.Text, personFieldElement.GroupSuffixPlural.FontStyle));
}
else if (showGroupSuffixIfPresent && !string.IsNullOrEmpty(personFieldElement.GroupSuffixSingular.Text) && !usePlural)
{
output.Add(new LiteralTextUnit(personFieldElement.GroupSuffixSingular.Text, personFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
handled = true;
return output;
#endregion Equality detected - generate output
}
#region GetPreviousVisibleCitation
private static Citation GetPreviousVisibleCitation(Citation citation)
{
if (citation == null) return null;
#region Bibliography
if (citation.CitationType == CitationType.Bibliography)
{
BibliographyCitation previousBibliographyCitation = citation as BibliographyCitation;
if (previousBibliographyCitation == null) return null;
//consider nobib
do
{
previousBibliographyCitation = previousBibliographyCitation.PreviousBibliographyCitation;
if (previousBibliographyCitation == null) return null;
} while (previousBibliographyCitation.NoBib == true);
//still here? found one!
return previousBibliographyCitation;
}
#endregion Bibliography
#region InText
if (citation.CitationType == CitationType.InText)
{
InTextCitation previousInTextCitation = citation as InTextCitation;
if (previousInTextCitation == null) return null;
//consider bibonly
do
{
previousInTextCitation = previousInTextCitation.PreviousInTextCitation;
if (previousInTextCitation == null) return null;
} while (previousInTextCitation.BibOnly == true);
//still here? found one!
return previousInTextCitation;
}
#endregion InText
#region Footnote
if (citation.CitationType == CitationType.Footnote)
{
FootnoteCitation previousFootnoteCitation = citation as FootnoteCitation;
if (previousFootnoteCitation == null) return null;
//consider bibonly
do
{
previousFootnoteCitation = previousFootnoteCitation.PreviousFootnoteCitation;
if (previousFootnoteCitation == null) return null;
} while (previousFootnoteCitation.BibOnly == true);
//still here? found one!
return previousFootnoteCitation;
}
#endregion Footnote
//still here? no visible previous citation found!
return null;
}
#endregion GetPreviousCitation
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
List persons = null;
if (element == null) return null;
if (reference == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (reference.Authors != null) persons = new List(reference.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (reference.Editors != null) persons = new List(reference.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (reference.AuthorsOrEditorsOrOrganizations != null) persons = new List(reference.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (reference.Collaborators != null) persons = new List(reference.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (reference.Organizations != null) persons = new List(reference.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (reference.OthersInvolved != null) persons = new List(reference.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
private static List GetPersonsDisplayed(ComponentPart componentPart, Reference reference)
{
List persons = null;
if (reference == null) return null;
if (componentPart == null) return null;
//check for 1st PersonFieldElement in ComponentPart
PersonFieldElement firstPersonFieldElement = componentPart.Elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
persons = GetPersonsDisplayed(firstPersonFieldElement, reference);
return persons;
}
private static List GetPersonsDisplayed(Template template, Reference reference)
{
if (reference == null) return null;
if (template == null) return null;
if (template.ComponentParts == null || template.ComponentParts.Count == 0) return null;
List persons = null;
//check for 1st PersonFieldElement in citation's template
IEnumerable elements = template.ComponentParts.SelectMany(part => part.Elements);
PersonFieldElement firstPersonFieldElement = elements.FirstOrDefault(item => item is PersonFieldElement) as PersonFieldElement;
if (firstPersonFieldElement == null) return null;
return GetPersonsDisplayed(firstPersonFieldElement, reference);
}
private static List GetPersonsDisplayed(Citation citation)
{
if (citation == null) return null;
if (citation.Reference == null) return null;
Template template = citation.GetTemplate();
if (template == null) return null;
List persons = null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
template = template.TemplateUseCase.FallbackTemplate;
if (template == null) return null;
persons = GetPersonsDisplayed(template, citation.Reference);
if (persons != null) return persons;
return null;
}
#endregion GetPersonsDisplayed
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(List personsA, List personsB)
{
if (personsA == null || personsA.Count == 0) return PersonEquality.None;
if (personsB == null || personsB.Count == 0) return PersonEquality.None;
if (personsA.Count != personsB.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
}
}
]]>
true
{0} (Hg.) [last name]
Always
Always
.
Reference
true
Editors
false
-1
LastNameOnly
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
Option1
true
false
false
Standard
false
{0}
Always
Always
.
ParentReference
true
Abstract
false
false
{0}
Always
Always
.
ParentReference
true
AccessDate
false
D
Always
im Druck
true
false
false
{0}
Always
Always
.
ParentReference
true
Additions
false
false
, in: {0}
Always
Always
,
ParentReference
true
Always
in:
Authors
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
AuthorsOrEditorsOrOrganizations
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
ParentReference
true
IndexInBibliography
false
Always
Arabic
Always
Always
LetterLowerCase
Always
Always
false
{0}
Always
Always
.
ParentReference
true
Categories
false
false
{0}
Always
Always
.
ParentReference
true
Collaborators
false
-1
LastNameFirstName
Full
Full
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
Evaluation
false
false
{0}
Always
Always
.
ParentReference
true
CreatedBy
false
false
{0}
Always
Always
.
ParentReference
true
Date
false
D
Always
im Druck
true
false
false
{0}
Always
Always
.
ParentReference
true
Date2
false
D
Always
im Druck
true
false
false
, {0}
Always
Always
,
ParentReference
true
Edition
false
Always
th
Always
Always
. Aufl.
Always
Always
. Aufl.
Always
1|st|2|nd|3|rd
Always
Always
false
false
, {0} edn.
Always
Always
,
ParentReference
true
EditionNumberResolved
false
Always
th
Always
Always
edn.
Always
Always
edn.
Always
1|st|2|nd|3|rd
Always
Always
true
false
{0}
Always
Always
.
ParentReference
true
Editors
false
-1
FirstNameLastName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
Always
Hg. v.
Always
Hg. v.
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
FirstFootnoteCitationNumber
false
false
false
false
{0}
Always
Always
.
ParentReference
true
CustomField1
false
false
{0}
Always
Always
.
ParentReference
true
CustomField2
false
false
{0}
Always
Always
.
ParentReference
true
CustomField3
false
false
{0}
Always
Always
.
ParentReference
true
CustomField4
false
false
{0}
Always
Always
.
ParentReference
true
Organizations
false
-1
LastNameFirstName
Full
Full
All
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
Isbn
false
false
{0}
Always
Always
.
ParentReference
true
Periodical
false
true
Name
false
{0}
Always
Always
.
ParentReference
true
Keywords
false
false
{0}
Always
Always
.
ParentReference
true
Language
false
false
{0}
Always
Always
.
ParentReference
true
ModifiedBy
false
false
{0}
Always
Always
.
ParentReference
true
Locations
false
false
{0}
Always
Always
.
ParentReference
true
Notes
false
false
{0}
Always
Always
.
ParentReference
true
Number
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
.
ParentReference
true
PageCount
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
,
ParentReference
true
NumberOfVolumes
false
Always
th
Always
Always
Bde
Always
Always
Bd.
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0}
Always
Always
.
ParentReference
true
OnlineAddress
false
false
false
false
false
false
{0}
Always
Always
.
ParentReference
true
OriginalCheckedBy
false
false
{0}
Always
Always
.
ParentReference
true
OriginalPublication
false
D
Always
im Druck
true
false
false
{0}
Always
Always
.
ParentReference
true
OthersInvolved
false
-1
LastNameFirstName
Abbreviated
Abbreviated
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
PageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
.
ParentReference
true
ParallelTitle
false
false
, {0}
Always
Always
,
ParentReference
true
PlaceOfPublication
false
true
3
1
Always
u. a.
Always
/
false
{0}
Always
Always
.
ParentReference
true
Price
false
false
: {0}
Always
Always
:
ParentReference
true
Publishers
false
false
{0}
Always
Always
.
ParentReference
true
QuotationPageRange
false
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
StartPageOnly
Always
Always
Always
false
FullRange
Always
Always
Always
Arabic
true
FullRange
Always
Always
–
Always
false
FullRange
Always
Always
Always
false
FullRange
Always
Always
Always
false
{0}
Always
Always
.
ParentReference
true
TextLinks
false
false
{0}
Always
Always
.
ParentReference
true
false
. {0}
Always
Always
.
ParentReference
true
SeriesTitle
false
true
Name
false
{0}
Always
Always
.
ParentReference
true
SeriesTitleEditors
false
-1
LastNameFirstName
Full
Full
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
{0}
Always
Always
.
ParentReference
true
ShortTitle
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField1
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField2
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField3
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField4
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField5
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField6
false
false
{0}
Always
Always
.
ParentReference
true
SpecificField7
false
false
{0}
Always
Always
.
ParentReference
true
StorageMedium
false
false
{0}
Always
Always
.
ParentReference
true
Tasks
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
: {0} [recte]
Always
Always
:
ParentReference
true
Title
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
. {0} [recte]
Always
Always
.
ParentReference
true
Subtitle
false
false
{0}
Always
Always
.
ParentReference
true
TitleInOtherLanguages
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//Name of filter: Convert output to title case (with exceptions, such as "and", "or" etc.)
//Version 1.9: Consider parent's Language field if this is a child reference and the child's Language field is empty
//Version 1.8: Parametrized conversion of full upper case words; functionality was impaired in version 1.7
//Version 1.7: Added checking for null on GetTextUnitsUnfiltered() to avoid NullReferenceExceptions at runtime (which may lead to auto-deactivation of filter)
//Version 1.6: ToUpperFirstLetter() method now handles words completely in UPPERCASE and takes culture into consideration
//Version 1.5: capitalize stopwords directly after quotation mark
//Version 1.4: improved word tokenization
//Version 1.3: ignore expressions which are written completely in upper case
//Version 1.2: new option to ensure that the reference language is "English"
var ensureEnglishIsReferenceLanguage = true; //if set to false, the component part filter will ALWAYS capitalize, regardless of the reference's language
var convertFullUpperCaseWords = ConvertFullUpperCaseWords.Never;
#region Info on ConvertFullUpperCaseWords parameter
/*
Example 1: UN and US government made agreement on payments of contribution
Example 2: UN AND US GOVERNMENT MADE AGREEMENT ON PAYMENTS OF CONTRIBUTION
ConvertFullUpperCaseWords.Never (default)
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: UN and US GOVERNMENT MADE AGREEMENT on PAYMENTS of CONTRIBUTION
ConvertFullUpperCaseWords.Always:
Result 1: Un and Us Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
ConvertFullUpperCaseWords.Auto:
Result 1: UN and US Government Made Agreement on Payments of Contribution
Result 2: Un and Us Government Made Agreement on Payments of Contribution
*/
#endregion
CultureInfo culture = CultureInfo.CurrentCulture;
handled = false;
if (citation == null) return null;
if (citation.Reference == null) return null;
if (componentPart == null) return null;
if (template == null) return null;
if (ensureEnglishIsReferenceLanguage)
{
string languageResolved = citation.Reference.Language;
if (componentPart.Scope == ComponentPartScope.Reference)
{
//if ComponentPartScope is Reference, language can come from Reference or ParentReference
if (string.IsNullOrEmpty(languageResolved) && citation.Reference.ParentReference != null)
{
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
}
else
{
//if ComponentPartScope is ParentReference, language MUST come from ParentReference
if (citation.Reference.ParentReference == null) return null;
languageResolved = citation.Reference.ParentReference.Language;
}
if (string.IsNullOrEmpty(languageResolved)) return null;
var termsList = new string[] {
"en",
"eng",
"engl",
"English",
"Englisch"
};
var regEx = new Regex(@"\b(" + string.Join("|", termsList) + @")\b", RegexOptions.IgnoreCase);
if (!regEx.IsMatch(languageResolved))
{
return null;
}
}
//Words that will not be capitalized; add words to this list as required
string[] exceptionsArray = { "a", "an", "and", "as", "at",
"but", "by", "down", "for", "from",
"in", "into", "nor",
"of", "on", "onto", "or", "over",
"so", "the", "till", "to",
"up", "via", "with", "yet" };
List exceptions = new List(exceptionsArray);
var textUnits = componentPart.GetTextUnitsUnfiltered(citation, template);
if (textUnits == null || !textUnits.Any()) return null;
string fullString = textUnits.ToString();
bool fullUpperCaseTreatment = false;
switch (convertFullUpperCaseWords)
{
case ConvertFullUpperCaseWords.Always:
fullUpperCaseTreatment = true;
break;
case ConvertFullUpperCaseWords.Never:
{
fullUpperCaseTreatment = false;
}
break;
default:
case ConvertFullUpperCaseWords.Auto:
{
if (HasLowerCase(fullString))
{
fullUpperCaseTreatment = false;
}
else
{
fullUpperCaseTreatment = true;
}
}
break;
}
string prevWord = string.Empty;
for (int i = 0; i < textUnits.Count; i++)
{
//textUnit.Text = textUnits[i].Text.ToLower(culture);
var text = textUnits[i].Text;
//Break the input text into a list of words at whitespaces,
//hyphens, opening parens, and ASCII quotation marks
string splitPattern = @"(\s)|(-)|(\()|(\"")";
List words = new List(Regex.Split(text, splitPattern));
var counter = 0;
text = string.Empty;
//Check each remaining word against the list, and append it to the new text.
//Leave words in upper case unchanged, unless they appear in the exception list.
foreach (string word in words)
{
counter++;
if (counter == 1) // first word in a textunit
{
if (i == 0) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // first word overall => capitalize
else if ((String.IsNullOrWhiteSpace(prevWord)) && !(exceptions.Contains(word.ToLower(culture)))) text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture); // new textunit after space and not stopword => capitalize
else text = text + word; // in all other cases: do nothing
}
else if (prevWord == @"""") // capitalize also stopwords directly after quotation marks
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
else if (exceptions.Contains(word.ToLower(culture))) // check list of exceptions
{
text = text + word.ToLower(culture);
}
else // in all other cases: capitalize
{
text = text + ToUpperFirstLetter(word, fullUpperCaseTreatment, culture);
}
prevWord = word; // save current word as previous word for next iteration
}
textUnits[i].Text = text;
}
handled = true;
return textUnits;
}
public string ToUpperFirstLetter(string input, bool ensureAllButFirstIsLower = false, CultureInfo culture = null)
{
if (string.IsNullOrEmpty(input)) return input;
char[] letters = input.ToCharArray();
for (var i = 0; i < letters.Length; i++)
{
if (i == 0)
{
letters[0] = char.ToUpper(letters[0], culture);
continue;
}
if (i > 0 && ensureAllButFirstIsLower == false) break;
letters[i] = char.ToLower(letters[i], culture);
}
return new string(letters);
}
public enum ConvertFullUpperCaseWords
{
Never,
Always,
Auto //converts full uppercase words to lower case only if the conmplete text is written in uppercase
};
public bool HasLowerCase (string input)
{
return !string.IsNullOrEmpty(input) && input.Any(c => char.IsLower(c));
}
}
}]]>
true
Title_ToTitleCase
. {0}
Always
Always
.
ParentReference
true
TitleSupplement
false
false
{0}
Always
Always
.
ParentReference
true
TableOfContents
false
false
{0}
Always
Always
.
ParentReference
true
CitationKey
false
false
false
{0}
Always
Always
.
ParentReference
true
TranslatedTitle
false
false
{0}
Always
Always
.
ParentReference
true
UniformTitle
false
false
, vol. {0}
Always
Always
,
ParentReference
true
Volume
false
Always
th
Always
vol.
Always
Always
vol.
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
_{0}
Always
Always
ParentReference
true
YearResolved
false
D
Always
im Druck
false
false
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//change the following to "true", if you want "ders."/"dies." written in italics or other font styles
var outputInItalics = false;
var outputInSmallCaps = false;
var outputInBold = false;
var outputUnderlined = false;
//NOTE: If you want a prefix such as "In: " and a suffix " (Hrsg)", you can define them as group prefix and suffix on the field element inside the component part editor
handled = false;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
if (citation == null) return null;
Reference reference = citation.Reference;
if (reference == null) return null;
Reference parentReference = citation.Reference.ParentReference;
#region ThisPersonFieldElement
PersonFieldElement thisPersonFieldElement = GetPersonFieldElement(componentPart);
if (thisPersonFieldElement == null) return null;
#endregion
#region ThesePersons
IList thesePersons = GetPersonsDisplayed(thisPersonFieldElement, reference);
#endregion
#region PreviousPersonFieldElement
PersonFieldElement previousPersonFieldElement = GetPreviousPersonFieldElement(thisPersonFieldElement, template, reference);
if (previousPersonFieldElement == null) return null;
#endregion
#region PreviousPersons
IList previousPersons = GetPersonsDisplayed(previousPersonFieldElement, reference);
if (previousPersons == null || !previousPersons.Any()) return null;
#endregion
bool usePlural = thesePersons.Count() > 1;
PersonEquality equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
var textIdem = string.Empty;
switch (equality)
{
case PersonEquality.M:
case PersonEquality.N:
textIdem = "ders.";
break;
default: //all others
textIdem = "dies.";
break;
}
TextUnitCollection output = new TextUnitCollection();
#region GroupPrefix
if (usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupPrefixPlural.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupPrefixPlural.Text, thisPersonFieldElement.GroupPrefixPlural.FontStyle));
}
else if (!usePlural & !string.IsNullOrEmpty(thisPersonFieldElement.GroupPrefixSingular.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupPrefixSingular.Text, thisPersonFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
SwissAcademic.Drawing.FontStyle fontStyle;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
var fontStyleNeutral = SwissAcademic.Drawing.FontStyle.Neutral;
output.Add(new LiteralTextUnit(textIdem, fontStyle));
#region GroupSuffix
if (usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupSuffixPlural.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupSuffixPlural.Text, thisPersonFieldElement.GroupSuffixPlural.FontStyle));
}
else if (!usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupSuffixSingular.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupSuffixSingular.Text, thisPersonFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
//inject this as LiteralElements into the componentPart, replacing the editors person field element
componentPart.Elements.ReplaceItem(thisPersonFieldElement, TextUnitsToLiteralElements(output, componentPart)); //for some reason this does not work
//all literal elements should always be output:
foreach (LiteralElement literalElement in componentPart.Elements.OfType())
{
literalElement.ApplyCondition = ElementApplyCondition.Always;
}
handled = false;
return null;
}
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(IList personsACollection, IList personsBCollection)
{
if (personsACollection == null || personsACollection.Count == 0) return PersonEquality.None;
if (personsBCollection == null || personsBCollection.Count == 0) return PersonEquality.None;
if (personsACollection.Count != personsBCollection.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
List personsA = personsACollection.ToList();
List personsB = personsBCollection.ToList();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region GetPersonFieldElement
private static PersonFieldElement GetPersonFieldElement(ComponentPart componentPart)
{
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
return componentPart.Elements.OfType().FirstOrDefault() as PersonFieldElement;
}
#endregion
#region GetPreviousPersonFieldElement
private static PersonFieldElement GetPreviousPersonFieldElement(PersonFieldElement thisPersonFieldElement, Template template, Reference reference)
{
if (thisPersonFieldElement == null) return null;
if (template == null || template.ComponentParts == null || !template.ComponentParts.Any()) return null;
IEnumerable allPersonFieldElements = template.ComponentParts.SelectMany(part => part.Elements).OfType().ToList();
if (allPersonFieldElements == null || !allPersonFieldElements.Any()) return null;
int thisIndex = allPersonFieldElements.FindIndex(item => item.Id == thisPersonFieldElement.Id);
if (thisIndex == -1 || thisIndex == 0) return null;
for (int i = thisIndex - 1; i >= 0; i--)
{
PersonFieldElement previousPersonFieldElement = allPersonFieldElements.ElementAtOrDefault(i) as PersonFieldElement;
if (previousPersonFieldElement == null) continue;
List previousPersons = GetPersonsDisplayed(previousPersonFieldElement, reference);
if (previousPersons == null || !previousPersons.Any()) continue;
return previousPersonFieldElement;
}
return null;
}
#endregion
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
if (element == null) return null;
if (element.ComponentPart == null) return null;
List persons = null;
ComponentPartScope scope = element.ComponentPart.Scope;
Reference referenceInScope = null;
if (scope == ComponentPartScope.Reference) referenceInScope = reference;
else referenceInScope = reference.ParentReference;
if (referenceInScope == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (referenceInScope.Authors != null) persons = new List(referenceInScope.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (referenceInScope.Editors != null) persons = new List(referenceInScope.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (referenceInScope.AuthorsOrEditorsOrOrganizations != null) persons = new List(referenceInScope.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (referenceInScope.Collaborators != null) persons = new List(referenceInScope.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (referenceInScope.Organizations != null) persons = new List(referenceInScope.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (referenceInScope.OthersInvolved != null) persons = new List(referenceInScope.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
#endregion
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
#region TextUnitsToLiteralElements
IEnumerable TextUnitsToLiteralElements(TextUnitCollection textUnits, ComponentPart componentPart)
{
if (componentPart == null) yield break;
if (textUnits == null || textUnits.Count == 0) yield break;
foreach (ITextUnit textUnit in textUnits)
{
LiteralElement element = new LiteralElement(componentPart, textUnit.Text, ElementApplyCondition.Always);
element.FontStyle = textUnit.FontStyle;
yield return element;
}
}
#endregion TextUnitsToLiteralElements
}
}]]>
true
, in: {0} (Hg.)
Always
Always
,
ParentReference
true
Always
in:
Editors
false
-1
FirstNameLastName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Hg.)
Always
(Hg.)
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
. In: {0}
Always
Always
.
ParentReference
true
Always
In:
Title
false
false
{0}
Always
Always
.
ParentReference
true
CustomField5
false
false
{0}
Always
Always
.
ParentReference
true
CustomField6
false
false
{0}
Always
Always
.
ParentReference
true
CustomField7
false
false
{0}
Always
Always
.
ParentReference
true
CustomField8
false
false
{0}
Always
Always
.
ParentReference
true
CustomField9
false
false
{0}
Always
Always
.
ParentReference
true
EditionNumberResolved
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
{0} ed.
Always
Always
.
ParentReference
true
Edition
false
Always
th
Always
Always
ed.
Always
Always
ed.
Always
1|st|2|nd|3|rd
Always
Always
true
false
. In: {0} (eds.)
Always
Always
.
ParentReference
true
Always
In:
Editors
false
-1
LastNameFirstName
Abbreviated
Abbreviated
All
Always
,
Always
,
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
false
3
1
Always
, et al.
false
false
false
false
Always
,
Always
(ed.)
Always
(eds.)
NameAbbreviation
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
: {0} [italic]
Always
Always
:
ParentReference
true
Subtitle
false
false
false
false
true
false
false
false
false
false
false
. {0} [italic]
Always
Always
.
ParentReference
true
Title
false
false
false
false
true
false
false
false
false
false
false
. In: {0} [italic]
Always
Always
.
ParentReference
true
Always
In:
Title
false
false
false
false
true
false
false
false
false
false
false
, {0}
Always
Always
,
ParentReference
true
Volume
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
false
_({0}, Band {1})
Always
Always
ParentReference
true
NextElementHasData
(
SeriesTitle
false
true
Name
NextElementHasData
,
Volume
false
Always
th
Always
Bd.
Always
Always
Bd.
Always
Always
1|st|2|nd|3|rd
Always
Always
false
PreviousElementHasData
)
false
, hg. v. {0}
Always
Always
,
ParentReference
true
Editors
false
-1
FirstNameLastName
Full
Full
All
Always
,
Always
und
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u.a.
false
false
false
false
Always
,
Always
hg. v.
Always
hg. v.
NameOnly
NextElementHasData
AttributeHasData
PreviousElementHasData
AttributeHasData
NextElementHasData
(
AttributeHasData
PreviousElementHasData
)
AttributeHasData
false
false
_({0} {1})
Always
Always
ParentReference
true
NextElementHasData
(
SeriesTitle
false
true
Name
Volume
false
Always
th
Always
Always
Always
Always
Always
1|st|2|nd|3|rd
Always
Always
false
AnyElementInComponentHasData
)
false
GetTextUnits(ComponentPart componentPart, Template template, Citation citation, out bool handled)
{
//change the following to "true", if you want "ders."/"dies." written in italics or other font styles
var outputInItalics = false;
var outputInSmallCaps = false;
var outputInBold = false;
var outputUnderlined = false;
//NOTE: If you want a prefix such as "In: " and a suffix " (Hrsg)", you can define them as group prefix and suffix on the field element inside the component part editor
handled = false;
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
if (citation == null) return null;
Reference reference = citation.Reference;
if (reference == null) return null;
Reference parentReference = citation.Reference.ParentReference;
#region ThisPersonFieldElement
PersonFieldElement thisPersonFieldElement = GetPersonFieldElement(componentPart);
if (thisPersonFieldElement == null) return null;
#endregion
#region ThesePersons
IList thesePersons = GetPersonsDisplayed(thisPersonFieldElement, reference);
#endregion
#region PreviousPersonFieldElement
PersonFieldElement previousPersonFieldElement = GetPreviousPersonFieldElement(thisPersonFieldElement, template, reference);
if (previousPersonFieldElement == null) return null;
#endregion
#region PreviousPersons
IList previousPersons = GetPersonsDisplayed(previousPersonFieldElement, reference);
if (previousPersons == null || !previousPersons.Any()) return null;
#endregion
bool usePlural = thesePersons.Count() > 1;
PersonEquality equality = CheckPersonEquality(thesePersons, previousPersons);
if (equality == PersonEquality.None) return null;
//we DO have some equality, so let's check what we need to output instead of the person's name(s)
var textIdem = string.Empty;
switch (equality)
{
case PersonEquality.M:
case PersonEquality.N:
textIdem = "ders.";
break;
default: //all others
textIdem = "dies.";
break;
}
TextUnitCollection output = new TextUnitCollection();
#region GroupPrefix
if (usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupPrefixPlural.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupPrefixPlural.Text, thisPersonFieldElement.GroupPrefixPlural.FontStyle));
}
else if (!usePlural & !string.IsNullOrEmpty(thisPersonFieldElement.GroupPrefixSingular.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupPrefixSingular.Text, thisPersonFieldElement.GroupPrefixSingular.FontStyle));
}
#endregion GroupPrefix
SwissAcademic.Drawing.FontStyle fontStyle;
fontStyle = SwissAcademic.Drawing.FontStyle.Neutral;
if (outputInItalics) fontStyle |= SwissAcademic.Drawing.FontStyle.Italic;
if (outputInSmallCaps) fontStyle |= SwissAcademic.Drawing.FontStyle.SmallCaps;
if (outputInBold) fontStyle |= SwissAcademic.Drawing.FontStyle.Bold;
if (outputUnderlined) fontStyle |= SwissAcademic.Drawing.FontStyle.Underline;
var fontStyleNeutral = SwissAcademic.Drawing.FontStyle.Neutral;
output.Add(new LiteralTextUnit(textIdem, fontStyle));
#region GroupSuffix
if (usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupSuffixPlural.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupSuffixPlural.Text, thisPersonFieldElement.GroupSuffixPlural.FontStyle));
}
else if (!usePlural && !string.IsNullOrEmpty(thisPersonFieldElement.GroupSuffixSingular.Text))
{
output.Add(new LiteralTextUnit(thisPersonFieldElement.GroupSuffixSingular.Text, thisPersonFieldElement.GroupSuffixSingular.FontStyle));
}
#endregion GroupSuffix
//inject this as LiteralElements into the componentPart, replacing the editors person field element
componentPart.Elements.ReplaceItem(thisPersonFieldElement, TextUnitsToLiteralElements(output, componentPart)); //for some reason this does not work
//all literal elements should always be output:
foreach (LiteralElement literalElement in componentPart.Elements.OfType())
{
literalElement.ApplyCondition = ElementApplyCondition.Always;
}
handled = false;
return null;
}
#region CheckPersonEquality
private static PersonEquality CheckPersonEquality(IList personsACollection, IList personsBCollection)
{
if (personsACollection == null || personsACollection.Count == 0) return PersonEquality.None;
if (personsBCollection == null || personsBCollection.Count == 0) return PersonEquality.None;
if (personsACollection.Count != personsBCollection.Count) return PersonEquality.None;
//we DO have two lists of persons of same length
//FIRST sort by id for comparison
var personIdComparer = new PersonIdComparer();
List personsA = personsACollection.ToList();
List personsB = personsBCollection.ToList();
personsA.Sort(personIdComparer);
personsB.Sort(personIdComparer);
var allCounter = personsA.Count;
var maleCounter = 0;
var femaleCounter = 0;
var neutralCounter = 0;
//loop, compare GUID/id and determine/count sex
for (int i = 0; i < personsA.Count; i++)
{
var idA = personsA[i].GetValue(PersonPropertyId.Id).ToString();
var idB = personsB[i].GetValue(PersonPropertyId.Id).ToString();
if (!idA.Equals(idB, StringComparison.Ordinal)) return PersonEquality.None;
//identical!
//determine sex (just need to look at one of them, because they are identical)
if (personsA[i].Sex == Sex.Male) maleCounter++;
if (personsA[i].Sex == Sex.Female) femaleCounter++;
if (personsA[i].Sex == Sex.Neutral || personsA[i].Sex == Sex.Unknown) neutralCounter++;
}
//still here, so ALL persons are equal, now return equality based on sex
if (allCounter == 1 && maleCounter == 1) return PersonEquality.M;
else if (allCounter == 1 && femaleCounter == 1) return PersonEquality.F;
else if (allCounter == 1 && neutralCounter == 1) return PersonEquality.N;
else if (allCounter > 1 && maleCounter == allCounter) return PersonEquality.MM;
else if (allCounter > 1 && femaleCounter == allCounter) return PersonEquality.FF;
else if (allCounter > 1 && neutralCounter == allCounter) return PersonEquality.NN;
else if (allCounter > 1 && maleCounter + femaleCounter == allCounter) return PersonEquality.FM;
else if (allCounter > 1 && femaleCounter + neutralCounter == allCounter) return PersonEquality.FN;
else if (allCounter > 1 && maleCounter + neutralCounter == allCounter) return PersonEquality.MN;
else if (allCounter >= 3
&& maleCounter >= 1 && femaleCounter >= 1 && neutralCounter >= 1
&& maleCounter + femaleCounter + neutralCounter == allCounter) return PersonEquality.FMN;
else return PersonEquality.None;
}
#endregion CheckPersonEquality
#region Enum PersonEquality
public enum PersonEquality
{
///
/// None: Different persons and/or different numbers of persons.
///
///
None,
///
/// Identical person, a single female (Latin: eadem)
///
F,
///
/// Identical person, a single male (Latin: idem)
///
M,
///
/// Identical persons, a single (neutral) organization (Latin: idem)
///
N,
///
/// Identical persons, only females, 2 or more (Latin: eaedem)
///
FF,
///
/// Identical persons, only males, 2 or more (Latin: eidem)
///
MM,
///
/// Identical persons, only (neutral) organizations, 2 or more (Latin: eadem)
///
NN,
///
/// Identical persons, mixed group of females and males only
///
FM,
///
/// Identical persons, mixed group of females and neutrals only
///
FN,
///
/// Identical persons, mixed group of males and neutrals only
///
MN,
///
/// Identical persons, mixed group of females, males and neutrals
///
FMN
}
#endregion PersonEquality
#region GetPersonFieldElement
private static PersonFieldElement GetPersonFieldElement(ComponentPart componentPart)
{
if (componentPart == null) return null;
if (componentPart.Elements == null || !componentPart.Elements.Any()) return null;
return componentPart.Elements.OfType().FirstOrDefault() as PersonFieldElement;
}
#endregion
#region GetPreviousPersonFieldElement
private static PersonFieldElement GetPreviousPersonFieldElement(PersonFieldElement thisPersonFieldElement, Template template, Reference reference)
{
if (thisPersonFieldElement == null) return null;
if (template == null || template.ComponentParts == null || !template.ComponentParts.Any()) return null;
IEnumerable allPersonFieldElements = template.ComponentParts.SelectMany(part => part.Elements).OfType().ToList();
if (allPersonFieldElements == null || !allPersonFieldElements.Any()) return null;
int thisIndex = allPersonFieldElements.FindIndex(item => item.Id == thisPersonFieldElement.Id);
if (thisIndex == -1 || thisIndex == 0) return null;
for (int i = thisIndex - 1; i >= 0; i--)
{
PersonFieldElement previousPersonFieldElement = allPersonFieldElements.ElementAtOrDefault(i) as PersonFieldElement;
if (previousPersonFieldElement == null) continue;
List previousPersons = GetPersonsDisplayed(previousPersonFieldElement, reference);
if (previousPersons == null || !previousPersons.Any()) continue;
return previousPersonFieldElement;
}
return null;
}
#endregion
#region GetPersonsDisplayed
private static List GetPersonsDisplayed(PersonFieldElement element, Reference reference)
{
if (element == null) return null;
if (element.ComponentPart == null) return null;
List persons = null;
ComponentPartScope scope = element.ComponentPart.Scope;
Reference referenceInScope = null;
if (scope == ComponentPartScope.Reference) referenceInScope = reference;
else referenceInScope = reference.ParentReference;
if (referenceInScope == null) return null;
switch (element.PropertyId)
{
#region Authors
case ReferencePropertyId.Authors:
{
if (referenceInScope.Authors != null) persons = new List(referenceInScope.Authors);
}
break;
#endregion Authors
#region Editors
case ReferencePropertyId.Editors:
{
if (referenceInScope.Editors != null) persons = new List(referenceInScope.Editors);
}
break;
#endregion Editors
#region AuthorsEditorsOrganizations
case ReferencePropertyId.AuthorsOrEditorsOrOrganizations:
{
if (referenceInScope.AuthorsOrEditorsOrOrganizations != null) persons = new List(referenceInScope.AuthorsOrEditorsOrOrganizations);
}
break;
#endregion AuthorsEditorsOrganizations
#region Collaborators
case ReferencePropertyId.Collaborators:
{
if (referenceInScope.Collaborators != null) persons = new List(referenceInScope.Collaborators);
}
break;
#endregion Collaborators
#region Organizations
case ReferencePropertyId.Organizations:
{
if (referenceInScope.Organizations != null) persons = new List(referenceInScope.Organizations);
}
break;
#endregion Organizations
#region OthersInvolved
case ReferencePropertyId.OthersInvolved:
{
if (referenceInScope.OthersInvolved != null) persons = new List(referenceInScope.OthersInvolved);
}
break;
#endregion OthersInvolved
}
return persons;
}
#endregion
#region PersonIdComparer
//The following is a sort comparer that will bring all person collections into a well defined order
//namely in the order of their internal GUID values.
public class PersonIdComparer : IComparer
{
public int Compare(Person person1, Person person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person1.GetValue(PersonPropertyId.Id).ToString().CompareTo(person2.GetValue(PersonPropertyId.Id).ToString());
}
return returnValue;
}
}
#endregion PersonIdComparer
#region TextUnitsToLiteralElements
IEnumerable TextUnitsToLiteralElements(TextUnitCollection textUnits, ComponentPart componentPart)
{
if (componentPart == null) yield break;
if (textUnits == null || textUnits.Count == 0) yield break;
foreach (ITextUnit textUnit in textUnits)
{
LiteralElement element = new LiteralElement(componentPart, textUnit.Text, ElementApplyCondition.Always);
element.FontStyle = textUnit.FontStyle;
yield return element;
}
}
#endregion TextUnitsToLiteralElements
}
}]]>
true
, in: {0} (Übers.)
Always
Always
,
ParentReference
true
Always
in:
Collaborators
false
-1
FirstNameLastName
Full
Full
All
Always
/
Always
/
false
false
false
false
Always
,
Always
Always
Always
.
LastNameFirstName
Full
Full
All
Always
;
Always
;
Always
;
false
false
false
false
Always
,
Always
Always
Always
.
false
LastNameFirstName
Full
Full
All
false
false
false
false
Always
,
Always
Always
Always
.
false
Always
;
true
3
1
Always
u. a.
false
false
false
false
Always
,
Always
(Übers.)
Always
(Übers.)
NameOnly
Always
AttributeHasData
Always
AttributeHasData
Always
(
AttributeHasData
Always
)
AttributeHasData
true
Always
Ders.
Always
Dies.
Always
Dass.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
Always
Dies.
false
true
true
false
false
true
true
None
false
false
Standard
false
false
Quellen- und Literaturverzeichnis
.
283
true
None
Arabic
1
0
;
true
0
Custom
AuthorsOrEditorsOrOrganizations
Ascending
Title
Ascending
YearResolved
Descending
Gruppiertes Literaturverzeichnis nach Freitext 1_Autor_Titel (ohne Stoppwörter??)
um Stoppwörter zu unterdrücken]]>
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 || x.Reference == null) return 0;
if (y == null || y.Reference == null) return 0;
bool xCustomFieldHasValue = !string.IsNullOrWhiteSpace(x.Reference.CustomField1);
bool yCustomFieldHasValue = !string.IsNullOrWhiteSpace(y.Reference.CustomField1);
int resultCustomField1Comparison = 0;
if (xCustomFieldHasValue && yCustomFieldHasValue)
{
resultCustomField1Comparison = x.Reference.CustomField1.CompareTo(y.Reference.CustomField1);
}
else if (xCustomFieldHasValue && !yCustomFieldHasValue)
{
resultCustomField1Comparison = sortEmptyCustomFieldOnTop? 1 : -1;
}
else if (!xCustomFieldHasValue && yCustomFieldHasValue)
{
resultCustomField1Comparison = sortEmptyCustomFieldOnTop? -1 : 1;
}
if (resultCustomField1Comparison != 0) return resultCustomField1Comparison;
IComparer defaultCitationComparer = null;
if (sortYearAscending)
{
defaultCitationComparer = CitationComparer.AuthorYearTitleOrNoAuthorThenTitleYearAscending;
}
else
{
defaultCitationComparer = CitationComparer.AuthorYearTitleOrNoAuthorThenTitleAscendingYearDescending;
}
return defaultCitationComparer.Compare(x, y);
}
private static string GetSortTitle (Reference reference)
{
//change CustomField1 to some other CustomFieldN where the sorting title can be found or
//place two slashes in front of the following line to NOT make use of a special sorting title field at all
//if (!string.IsNullOrEmpty(reference.CustomField1)) return reference.CustomField1;
//still here? Then the sort title is derived from the title
var particlesToIgnore = new string[] {
"am",
"an",
"auf",
"das",
"der",
"die",
"ein",
"eine",
"im",
"in",
"inmitten",
"nach",
"über",
"ueber",
"vom",
"von",
"von",
"was",
"wie",
"wo",
"zu",
"zum",
"zur",
"zwischen",
"a",
"the",
"le",
"la",
"les"
};
var particlesRegEx = new Regex(@"\b(" + string.Join("|", particlesToIgnore) + @")\b", RegexOptions.IgnoreCase);
var wordsRegex = new Regex(@"[^\p{L}]*\p{Z}[^\p{L}]*");
string sortTitle = string.Empty;
var titleWords = wordsRegex.Split(reference.Title.Trim());
int firstNonParticleToIgnoreIndex = -1;
foreach (string word in titleWords)
{
if (string.IsNullOrEmpty(word)) break;
firstNonParticleToIgnoreIndex++;
if (!particlesRegEx.IsMatch(word)) break;
}
if (firstNonParticleToIgnoreIndex == -1) return reference.Title; //either title is empty or consists of particles to ignore ONLY
if (firstNonParticleToIgnoreIndex == 0) return reference.Title; //title starts with a relevant word
//"[" + string.Join(" ", titleWords, 0, firstNonParticleIndex) + "] " + string.Join(" ", titleWords, firstNonParticleIndex, titleWords.Length - firstNonParticleIndex);
return string.Join(" ", titleWords, firstNonParticleToIgnoreIndex, titleWords.Length - firstNonParticleToIgnoreIndex);
}
}
}]]>
OrderOfAppearance
LetterLowerCase
false
)
false
•
Completed
None
JournalArticle
true
DoiAvailable
VolumeMissing
NumberMissing
PageRangeMissing
YearMissing
Completed
None
Book
true
Completed
None
BookEdited
true
Completed
BookEdited
Contribution
true
DoiAvailable
Completed
ContributionBookEdited
UnpublishedWork
Contribution
true
Completed
CollectedWorks
Contribution
true
ParentReferenceEditorsMissing
Completed
ContributionBookEdited
ConferenceProceedings
Contribution
true
NeedsReview
JournalArticle
SpecialIssue
Contribution
true
Completed
None
InternetDocument
true
Completed
None
Thesis
true
Completed
None
NewspaperArticle
true
NeedsReview
Unknown
None
UnpublishedWork
true
Completed
None
Unknown
true
Completed
None
ArchiveMaterial
true
NeedsReview
ContributionBookEdited
BookEdited
ArchiveMaterial
false
NeedsReview
ContributionBookEdited
UnpublishedWork
ArchiveMaterial
false
NeedsReview
ContributionBookEdited
CollectedWorks
ArchiveMaterial
false
NeedsReview
Book
None
AudioBook
true
NeedsReview
Book
None
AudioOrVideoDocument
true
NeedsReview
Unknown
None
RadioPlay
true
Completed
None
CollectedWorks
true
CollaboratorsAvailable
EditorsMissing
NeedsReview
Book
None
ComputerProgram
true
Completed
BookEdited
None
ConferenceProceedings
true
NeedsReview
Unknown
None
CourtDecision
true
NeedsReview
Unknown
None
InterviewMaterial
true
NeedsReview
Book
None
Map
true
Completed
None
Movie
true
NeedsReview
Unknown
None
MusicTrack
true
NeedsReview
ContributionBookEdited
MusicAlbum
MusicTrack
true
NeedsReview
Book
None
NewsAgencyReport
true
NeedsReview
Unknown
None
Patent
true
NeedsReview
Unknown
None
PersonalCommunication
true
NeedsReview
Book
None
PressRelease
true
NeedsReview
RadioPlay
None
Broadcast
true
NeedsReview
ArchiveMaterial
None
File
true
NeedsReview
Unknown
None
MusicAlbum
true
NeedsReview
Unknown
None
Standard
true
NeedsReview
Book
None
StatuteOrRegulation
true
NeedsReview
ContributionBookEdited
BookEdited
StatuteOrRegulation
true
NeedsReview
Book
None
Manuscript
true
NeedsReview
Book
None
Lecture
true
NeedsReview
BookEdited
None
LegalCommentary
true
Completed
ContributionBookEdited
LegalCommentary
ContributionInLegalCommentary
true
UnderConstruction
None
SpecialIssue
false
true
false
OrderOfAppearance
false
None
None
JournalArticle
false
DoiAvailable
Feld "Jahrgang" ist leer
DoiAvailable
VolumeMissing
YearMissing
DoiAvailable
RepeatingFootnoteNonConsecutive
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAndSamePageAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
Unknown
None
Book
false
None
None
BookEdited
false
RepeatingFootnoteNonConsecutive
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAndSamePageAsPrevious
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
BookEdited
Contribution
false
DoiAvailable
RepeatingFootnoteNonConsecutive
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAndSamePageAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
Nachweis mit "Option 2"
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
ContributionBookEdited
UnpublishedWork
Contribution
false
None
ContributionBookEdited
CollectedWorks
Contribution
false
None
ContributionBookEdited
ConferenceProceedings
Contribution
false
None
JournalArticle
SpecialIssue
Contribution
false
None
None
InternetDocument
false
SameReferenceAsPrevious
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
Book
None
Thesis
false
None
None
NewspaperArticle
false
RepeatingFootnoteNonConsecutive
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAndSamePageAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
Unknown
None
UnpublishedWork
false
None
None
Unknown
false
RepeatingFootnoteNonConsecutive
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
SameReferenceAndSamePageAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
Unknown
None
ArchiveMaterial
false
None
ContributionBookEdited
BookEdited
ArchiveMaterial
false
None
ContributionBookEdited
UnpublishedWork
ArchiveMaterial
false
None
ContributionBookEdited
CollectedWorks
ArchiveMaterial
false
None
Book
None
AudioBook
false
None
Book
None
AudioOrVideoDocument
false
None
Unknown
None
RadioPlay
false
None
BookEdited
None
CollectedWorks
false
None
Book
None
ComputerProgram
false
None
BookEdited
None
ConferenceProceedings
false
None
Unknown
None
CourtDecision
false
None
Unknown
None
InterviewMaterial
false
None
Book
None
Map
false
None
None
Movie
false
RepeatingFootnoteNonConsecutive
SameReferenceAsPrevious
PreviousReferenceIsNotPartOfMultipleCitation
PlaceholderCitationFormatOption2
PlaceholderCitationFormatOption1
None
Unknown
None
MusicTrack
false
None
ContributionBookEdited
MusicAlbum
MusicTrack
false
None
Book
None
NewsAgencyReport
false
None
Unknown
None
Patent
false
None
Unknown
None
PersonalCommunication
false
None
Book
None
PressRelease
false
None
RadioPlay
None
Broadcast
false
None
Unknown
None
File
false
None
Unknown
None
MusicAlbum
false
None
Unknown
None
Standard
false
None
Book
None
StatuteOrRegulation
false
None
ContributionBookEdited
BookEdited
StatuteOrRegulation
false
None
Book
None
Manuscript
false
None
Book
None
Lecture
false
None
BookEdited
None
LegalCommentary
false
None
ContributionBookEdited
LegalCommentary
ContributionInLegalCommentary
false
None
Unknown
None
SpecialIssue
false
false
false
false
;
;
true
3
–
true
3
–
AlwaysButOncePerRange
true
OrderOfAppearance
false
None
Unknown
None
JournalArticle
false
None
Unknown
None
Book
false
None
Unknown
None
BookEdited
false
None
Unknown
BookEdited
Contribution
false
None
ContributionBookEdited
UnpublishedWork
Contribution
false
None
ContributionBookEdited
CollectedWorks
Contribution
false
None
ContributionBookEdited
ConferenceProceedings
Contribution
false
None
JournalArticle
SpecialIssue
Contribution
false
None
Unknown
None
InternetDocument
false
None
Book
None
Thesis
false
None
Unknown
None
NewspaperArticle
false
None
Unknown
None
UnpublishedWork
false
None
None
Unknown
false
None
Unknown
None
ArchiveMaterial
false
None
ContributionBookEdited
BookEdited
ArchiveMaterial
false
None
ContributionBookEdited
UnpublishedWork
ArchiveMaterial
false
None
ContributionBookEdited
CollectedWorks
ArchiveMaterial
false
None
Book
None
AudioBook
false
None
Book
None
AudioOrVideoDocument
false
None
Unknown
None
RadioPlay
false
None
BookEdited
None
CollectedWorks
false
None
Book
None
ComputerProgram
false
None
BookEdited
None
ConferenceProceedings
false
None
Unknown
None
CourtDecision
false
None
Unknown
None
InterviewMaterial
false
None
Book
None
Map
false
None
Book
None
Movie
false
None
Unknown
None
MusicTrack
false
None
ContributionBookEdited
MusicAlbum
MusicTrack
false
None
Book
None
NewsAgencyReport
false
None
Unknown
None
Patent
false
None
Unknown
None
PersonalCommunication
false
None
Book
None
PressRelease
false
None
RadioPlay
None
Broadcast
false
None
Unknown
None
File
false
None
Unknown
None
MusicAlbum
false
None
Unknown
None
Standard
false
None
Book
None
StatuteOrRegulation
false
None
ContributionBookEdited
BookEdited
StatuteOrRegulation
false
None
Book
None
Manuscript
false
None
Book
None
Lecture
false
None
BookEdited
None
LegalCommentary
false
None
ContributionBookEdited
LegalCommentary
ContributionInLegalCommentary
false
None
BookEdited
None
SpecialIssue
false