001package com.hfg.citation;
002
003import java.net.MalformedURLException;
004import java.net.URL;
005
006import com.hfg.css.CSS;
007import com.hfg.exception.ProgrammingException;
008import com.hfg.html.HTMLTag;
009import com.hfg.html.Span;
010import com.hfg.util.StringBuilderPlus;
011import com.hfg.util.StringUtil;
012import com.hfg.util.collection.CollectionUtil;
013import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlParagraph;
014import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlXMLTag;
015
016
017//------------------------------------------------------------------------------
018/**
019 Chicago Manual of Style (CMS) citation style.
020 <br/>
021 Example:
022 <pre>
023 Taylor, J. Alex, and Richard S. Johnson. “Sequence Database Searches Via de Novo Peptide Sequencing
024   by Tandem Mass Spectrometry.” Rapid Communications in Mass Spectrometry 11, no. 9 (1997): 1067–75.
025   doi:10.1002/(sici)1097-0231(19970615)11:9&lt;1067::aid-rcm953&gt;3.0.co;2-l.
026 </pre>
027 <div>
028 @author J. Alex Taylor, hairyfatguy.com
029 </div>
030 */
031//------------------------------------------------------------------------------
032// com.hfg XML/HTML Coding Library
033//
034// This library is free software; you can redistribute it and/or
035// modify it under the terms of the GNU Lesser General Public
036// License as published by the Free Software Foundation; either
037// version 2.1 of the License, or (at your option) any later version.
038//
039// This library is distributed in the hope that it will be useful,
040// but WITHOUT ANY WARRANTY; without even the implied warranty of
041// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
042// Lesser General Public License for more details.
043//
044// You should have received a copy of the GNU Lesser General Public
045// License along with this library; if not, write to the Free Software
046// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
047//
048// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
049// jataylor@hairyfatguy.com
050//------------------------------------------------------------------------------
051
052public class Chicago implements CitationFormat
053{
054   //##########################################################################
055   // PUBLIC METHODS
056   //##########################################################################
057
058   //---------------------------------------------------------------------------
059   @Override
060   public String generateAsString(Citation inCitation)
061   {
062      String formattedCitation;
063
064      switch (inCitation.getType())
065      {
066         case journal:
067            formattedCitation = generateJournalCitationAsString(inCitation);
068            break;
069         case software:
070            formattedCitation = generateSoftwareCitationAsString(inCitation);
071            break;
072         default:
073            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
074      }
075
076      return formattedCitation;
077   }
078
079   //---------------------------------------------------------------------------
080   @Override
081   public HTMLTag generateAsHTML(Citation inCitation)
082   {
083      HTMLTag tag;
084
085      switch (inCitation.getType())
086      {
087         case journal:
088            tag = generateJournalCitationAsHTML(inCitation);
089            break;
090         case software:
091            tag = generateSoftwareCitationAsHTML(inCitation);
092            break;
093         default:
094            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
095      }
096
097      return tag;
098   }
099
100   //---------------------------------------------------------------------------
101   @Override
102   public WmlParagraph generateAsDocx(Citation inCitation, WmlXMLTag inParentTag)
103   {
104      WmlParagraph p;
105
106      switch (inCitation.getType())
107      {
108         case journal:
109            p = generateJournalCitationAsDocx(inCitation, inParentTag);
110            break;
111         case software:
112            p = generateSoftwareCitationAsDocx(inCitation, inParentTag);
113            break;
114         default:
115            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
116      }
117
118      return p;
119   }
120
121   //##########################################################################
122   // PRIVATE METHODS
123   //##########################################################################
124
125   //---------------------------------------------------------------------------
126   private String generateAuthorListForBibliography(Citation inCitation)
127   {
128      StringBuilderPlus authorList = null;
129
130      if (CollectionUtil.hasValues(inCitation.getAuthors()))
131      {
132         authorList = new StringBuilderPlus().setDelimiter(", ");
133
134         for (int i = 1; i <= inCitation.getAuthors().size(); i++)
135         {
136            Author author = inCitation.getAuthors().get(i - 1);
137
138            if (1 == i)
139            {
140               // First Author
141               authorList.append(author.getLastName());
142               authorList.delimitedAppend(author.getFirstName());
143               if (1 == author.getFirstName().length())
144               {
145                  authorList.append(".");
146               }
147
148               Character middleInitial = author.getMiddleInitial();
149               if (middleInitial != null)
150               {
151                  authorList.append(" " + middleInitial + ".");
152               }
153            }
154            else if (inCitation.getAuthors().size() == i)
155            {
156               // Last author
157               authorList.delimitedAppend("and ");
158
159               authorList.append(author.getFirstName());
160               if (1 == author.getFirstName().length())
161               {
162                  authorList.append(".");
163               }
164
165               Character middleInitial = author.getMiddleInitial();
166               if (middleInitial != null)
167               {
168                  authorList.append(" " + middleInitial + ".");
169               }
170
171               authorList.append(" " + author.getLastName());
172            }
173            else
174            {
175               authorList.delimitedAppend(author.getFirstName());
176               if (1 == author.getFirstName().length())
177               {
178                  authorList.append(".");
179               }
180
181               Character middleInitial = author.getMiddleInitial();
182               if (middleInitial != null)
183               {
184                  authorList.append(" " + middleInitial + ".");
185               }
186
187               authorList.append(" " + author.getLastName());
188            }
189         }
190      }
191
192      return authorList != null ? authorList.toString() : null;
193   }
194
195   //---------------------------------------------------------------------------
196   private String generateJournalCitationAsString(Citation inCitation)
197   {
198      return StringUtil.stripHTMLTags(generateJournalCitationAsHTML(inCitation).toHTML());
199   }
200
201   //---------------------------------------------------------------------------
202   private HTMLTag generateJournalCitationAsHTML(Citation inCitation)
203   {
204      Span tag = new Span();
205
206      String authorList = generateAuthorListForBibliography(inCitation);
207
208      if (StringUtil.isSet(authorList))
209      {
210         tag.addContent(authorList);
211      }
212
213      if (StringUtil.isSet(inCitation.getTitle()))
214      {
215         tag.addContent(" \"" + inCitation.getTitle() + ",\"");
216      }
217
218      if (inCitation.getJournal() != null)
219      {
220         String journalString = inCitation.getJournal().getAbbrev();
221         if (null == journalString)
222         {
223            journalString = inCitation.getJournal().getTitle();
224         }
225
226         tag.addContent(" ");
227         tag.addSpan(journalString).addStyle(CSS.ITALIC);
228         tag.addContent(", ");
229      }
230
231      if (StringUtil.isSet(inCitation.getVolume()))
232      {
233         tag.addContent(" " + inCitation.getVolume());
234      }
235
236      if (StringUtil.isSet(inCitation.getIssue()))
237      {
238         tag.addContent(", no. " + inCitation.getIssue());
239      }
240
241      if (inCitation.getYear() != null)
242      {
243         tag.addContent(" (" + inCitation.getYear() + ")");
244      }
245
246      if (StringUtil.isSet(inCitation.getPages()))
247      {
248         tag.addContent(": " + inCitation.getPages() + ".");
249      }
250
251      if (StringUtil.isSet(inCitation.getDOI()))
252      {
253         tag.addContent(" ");
254         if (!inCitation.getDOI().startsWith("doi"))
255         {
256            tag.addContent("doi:");
257         }
258         tag.addContent(inCitation.getDOI());
259      }
260
261      if (StringUtil.isSet(inCitation.getURL()))
262      {
263         tag.addContent(" ");
264         tag.addLink(inCitation.getURL(), inCitation.getURL());
265      }
266
267      return tag;
268   }
269
270   //---------------------------------------------------------------------------
271   private WmlParagraph generateJournalCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
272   {
273      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
274      inParentTag.addSubtag(p);
275
276      String authorList = generateAuthorListForBibliography(inCitation);
277
278      if (StringUtil.isSet(authorList))
279      {
280         p.addTextRun(authorList);
281      }
282
283      if (StringUtil.isSet(inCitation.getTitle()))
284      {
285         p.addTextRun(" \"" + inCitation.getTitle() + ",\"");
286      }
287
288      if (inCitation.getJournal() != null)
289      {
290         String journalString = inCitation.getJournal().getAbbrev();
291         if (null == journalString)
292         {
293            journalString = inCitation.getJournal().getTitle();
294         }
295
296         p.addTextRun(" ");
297         p.addTextRun(journalString).getProperties().setItalics();
298         p.addTextRun(", ");
299      }
300
301      if (StringUtil.isSet(inCitation.getVolume()))
302      {
303         p.addTextRun(" " + inCitation.getVolume());
304      }
305
306      if (StringUtil.isSet(inCitation.getIssue()))
307      {
308         p.addTextRun(", no. " + inCitation.getIssue());
309      }
310
311      if (inCitation.getYear() != null)
312      {
313         p.addTextRun(" (" + inCitation.getYear() + ")");
314      }
315
316      if (StringUtil.isSet(inCitation.getPages()))
317      {
318         p.addTextRun(": " + inCitation.getPages() + ".");
319      }
320
321      if (StringUtil.isSet(inCitation.getDOI()))
322      {
323         p.addTextRun(" ");
324         if (!inCitation.getDOI().startsWith("doi"))
325         {
326            p.addTextRun("doi:");
327         }
328         p.addTextRun(inCitation.getDOI());
329      }
330
331      if (StringUtil.isSet(inCitation.getURL()))
332      {
333         p.addTextRun(" ");
334         try
335         {
336            p.addHyperlink(new URL(inCitation.getURL()), inCitation.getURL());
337         }
338         catch (MalformedURLException e)
339         {
340            throw new RuntimeException(e);
341         }
342      }
343
344      return p;
345   }
346
347   //---------------------------------------------------------------------------
348   private String generateSoftwareCitationAsString(Citation inCitation)
349   {
350      return StringUtil.stripHTMLTags(generateSoftwareCitationAsHTML(inCitation).toHTML());
351   }
352
353   //---------------------------------------------------------------------------
354   private HTMLTag generateSoftwareCitationAsHTML(Citation inCitation)
355   {
356      Span tag = new Span();
357
358      String authorList = generateAuthorListForBibliography(inCitation);
359
360
361      if (StringUtil.isSet(authorList))
362      {
363         tag.addContent(authorList + ".");
364      }
365
366
367      if (StringUtil.isSet(inCitation.getTitle()))
368      {
369         tag.addSpan(inCitation.getTitle()).addStyle(CSS.ITALIC);
370
371         if (StringUtil.isSet(inCitation.getVersion()))
372         {
373            tag.addContent(" (version " + inCitation.getVersion() + ")");
374         }
375
376         tag.addContent(" [Computer software].");
377      }
378
379      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
380      {
381         tag.addContent(" " + inCitation.getPlaceOfPublication() + ":");
382      }
383
384      if (StringUtil.isSet(inCitation.getPublisher()))
385      {
386         tag.addContent(" " + inCitation.getPublisher()
387               + (inCitation.getPublisher().endsWith(".") ? "" : "."));
388      }
389
390      if (inCitation.getYear() != null)
391      {
392         tag.addContent(", " + inCitation.getYear() + ".");
393      }
394
395      return tag;
396   }
397
398
399
400   //---------------------------------------------------------------------------
401   private WmlParagraph generateSoftwareCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
402   {
403      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
404      inParentTag.addSubtag(p);
405
406      String authorList = generateAuthorListForBibliography(inCitation);
407
408      if (StringUtil.isSet(authorList))
409      {
410         p.addTextRun(authorList + ".");
411      }
412
413
414      if (StringUtil.isSet(inCitation.getTitle()))
415      {
416         p.addTextRun(inCitation.getTitle()).getProperties().setItalics();
417
418         if (StringUtil.isSet(inCitation.getVersion()))
419         {
420            p.addTextRun(" (version " + inCitation.getVersion() + ")");
421         }
422
423         p.addTextRun(" [Computer software].");
424      }
425
426      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
427      {
428         p.addTextRun(" " + inCitation.getPlaceOfPublication() + ":");
429      }
430
431      if (StringUtil.isSet(inCitation.getPublisher()))
432      {
433         p.addTextRun(" " + inCitation.getPublisher()
434               + (inCitation.getPublisher().endsWith(".") ? "" : "."));
435      }
436
437      if (inCitation.getYear() != null)
438      {
439         p.addTextRun(", " + inCitation.getYear() + ".");
440      }
441
442      return p;
443   }
444}