001package com.hfg.citation;
002
003
004import com.hfg.css.CSS;
005import com.hfg.datetime.ThreadSafeDateFormat;
006import com.hfg.exception.ProgrammingException;
007import com.hfg.html.HTMLTag;
008import com.hfg.html.Span;
009import com.hfg.util.StringBuilderPlus;
010import com.hfg.util.StringUtil;
011import com.hfg.util.collection.CollectionUtil;
012import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlParagraph;
013import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlXMLTag;
014
015//------------------------------------------------------------------------------
016/**
017 Modern Language Association (MLA) citation style.
018 <br/>
019 Example:
020 <pre>
021 <span style='font-style:italic'>Author(s). "Title of Article." Title of Journal, Volume, Issue, Year, pages.</span>
022
023 Taylor, J. Alex, and Richard S. Johnson. “Sequence Database Searches Via de Novo Peptide Sequencing by Tandem
024   Mass Spectrometry.” Rapid Communications in Mass Spectrometry, vol. 11, no. 9, 1997, pp. 1067–1075.,
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 MLA implements CitationFormat
053{
054   private static ThreadSafeDateFormat sDateFormat = new ThreadSafeDateFormat("d MMM. YYYY");
055
056
057   //##########################################################################
058   // PUBLIC METHODS
059   //##########################################################################
060
061   //---------------------------------------------------------------------------
062   @Override
063   public String generateAsString(Citation inCitation)
064   {
065      String formattedCitation;
066
067      switch (inCitation.getType())
068      {
069         case journal:
070            formattedCitation = generateJournalCitationAsString(inCitation);
071            break;
072         case software:
073            formattedCitation = generateSoftwareCitationAsString(inCitation);
074            break;
075         default:
076            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
077      }
078
079      return formattedCitation;
080   }
081
082   //---------------------------------------------------------------------------
083   @Override
084   public HTMLTag generateAsHTML(Citation inCitation)
085   {
086      HTMLTag tag;
087
088      switch (inCitation.getType())
089      {
090         case journal:
091            tag = generateJournalCitationAsHTML(inCitation);
092            break;
093         case software:
094            tag = generateSoftwareCitationAsHTML(inCitation);
095            break;
096         default:
097            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
098      }
099
100      return tag;
101   }
102
103   //---------------------------------------------------------------------------
104   @Override
105   public WmlParagraph generateAsDocx(Citation inCitation, WmlXMLTag inParentTag)
106   {
107      WmlParagraph p;
108
109      switch (inCitation.getType())
110      {
111         case journal:
112            p = generateJournalCitationAsDocx(inCitation, inParentTag);
113            break;
114         case software:
115            p = generateSoftwareCitationAsDocx(inCitation, inParentTag);
116            break;
117         default:
118            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
119      }
120
121      return p;
122   }
123
124   //###########################################################################
125   // PRIVATE METHODS
126   //###########################################################################
127
128   //---------------------------------------------------------------------------
129   // Last, First M., and First M. Last.
130   private String generateAuthorListForBibliography(Citation inCitation)
131   {
132      StringBuilderPlus authorList = null;
133
134      if (CollectionUtil.hasValues(inCitation.getAuthors()))
135      {
136         authorList = new StringBuilderPlus().setDelimiter(", ");
137
138         for (int i = 1; i <= inCitation.getAuthors().size(); i++)
139         {
140            Author author = inCitation.getAuthors().get(i - 1);
141
142            if (1 == i)
143            {
144               // First Author
145               authorList.append(author.getLastName());
146               authorList.delimitedAppend(author.getFirstName());
147               if (1 == author.getFirstName().length())
148               {
149                  authorList.append(".");
150               }
151
152               Character middleInitial = author.getMiddleInitial();
153               if (middleInitial != null)
154               {
155                  authorList.append(" " + middleInitial + ".");
156               }
157            }
158            else if (inCitation.getAuthors().size() == i)
159            {
160               // Last author
161               authorList.delimitedAppend("and ");
162
163               authorList.append(author.getFirstName());
164               if (1 == author.getFirstName().length())
165               {
166                  authorList.append(".");
167               }
168
169               Character middleInitial = author.getMiddleInitial();
170               if (middleInitial != null)
171               {
172                  authorList.append(" " + middleInitial + ".");
173               }
174
175               authorList.append(" " + author.getLastName());
176            }
177            else
178            {
179               authorList.delimitedAppend(author.getFirstName());
180               if (1 == author.getFirstName().length())
181               {
182                  authorList.append(".");
183               }
184
185               Character middleInitial = author.getMiddleInitial();
186               if (middleInitial != null)
187               {
188                  authorList.append(" " + middleInitial + ".");
189               }
190
191               authorList.append(" " + author.getLastName());
192            }
193         }
194
195         if (! authorList.endsWith("."))
196         {
197            authorList.append(".");
198         }
199      }
200
201      return authorList != null ? authorList.toString() : null;
202   }
203
204   //---------------------------------------------------------------------------
205   private String generateJournalCitationAsString(Citation inCitation)
206   {
207      return StringUtil.stripHTMLTags(generateJournalCitationAsHTML(inCitation).toHTML());
208   }
209
210   //---------------------------------------------------------------------------
211   private HTMLTag generateJournalCitationAsHTML(Citation inCitation)
212   {
213      Span tag = new Span();
214
215      String authorList = generateAuthorListForBibliography(inCitation);
216
217      if (StringUtil.isSet(authorList))
218      {
219         tag.addContent(authorList);
220      }
221
222      if (StringUtil.isSet(inCitation.getTitle()))
223      {
224         tag.addContent(" \"" + inCitation.getTitle() + ".\"");
225      }
226
227      if (inCitation.getJournal() != null)
228      {
229         String journalString = inCitation.getJournal().getAbbrev();
230         if (null == journalString)
231         {
232            journalString = inCitation.getJournal().getTitle();
233         }
234
235         tag.addContent(" ");
236         tag.addSpan(journalString).addStyle(CSS.ITALIC);
237      }
238
239      if (StringUtil.isSet(inCitation.getVolume()))
240      {
241         tag.addContent(" ");
242         tag.addContent(inCitation.getVolume());
243         tag.addContent(".");
244      }
245
246      if (StringUtil.isSet(inCitation.getIssue()))
247      {
248         tag.addContent(inCitation.getIssue());
249      }
250
251      if (inCitation.getYear() != null)
252      {
253         tag.addContent(" (" + inCitation.getYear() + ")");
254      }
255
256      if (StringUtil.isSet(inCitation.getPages()))
257      {
258         tag.addContent(": " + inCitation.getPages() + ".");
259      }
260
261      if (! StringUtil.isSet(inCitation.getWebsiteTitle()))
262      {
263         tag.addContent(" Print.");
264      }
265      else
266      {
267         tag.addContent(inCitation.getWebsiteTitle());
268         tag.addContent(". Web. ");
269         if (inCitation.getAccessDate() != null)
270         {
271            tag.addContent(sDateFormat.format(inCitation.getAccessDate()));
272            tag.addContent(".");
273         }
274      }
275
276      return tag;
277   }
278
279   //---------------------------------------------------------------------------
280   private WmlParagraph generateJournalCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
281   {
282      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
283      inParentTag.addSubtag(p);
284
285      String authorList = generateAuthorListForBibliography(inCitation);
286
287      if (StringUtil.isSet(authorList))
288      {
289         p.addTextRun(authorList);
290      }
291
292
293      if (StringUtil.isSet(inCitation.getTitle()))
294      {
295         p.addTextRun(" \"" + inCitation.getTitle() + ".\"");
296      }
297
298      if (inCitation.getJournal() != null)
299      {
300         String journalString = inCitation.getJournal().getAbbrev();
301         if (null == journalString)
302         {
303            journalString = inCitation.getJournal().getTitle();
304         }
305
306         p.addTextRun(" ");
307         p.addTextRun(journalString).getProperties().setItalics();
308      }
309
310      if (StringUtil.isSet(inCitation.getVolume()))
311      {
312         p.addTextRun(" ");
313         p.addTextRun(inCitation.getVolume());
314         p.addTextRun(".");
315      }
316
317      if (StringUtil.isSet(inCitation.getIssue()))
318      {
319         p.addTextRun(inCitation.getIssue());
320      }
321
322      if (inCitation.getYear() != null)
323      {
324         p.addTextRun(" (" + inCitation.getYear() + ")");
325      }
326
327      if (StringUtil.isSet(inCitation.getPages()))
328      {
329         p.addTextRun(": " + inCitation.getPages() + ".");
330      }
331
332      if (! StringUtil.isSet(inCitation.getWebsiteTitle()))
333      {
334         p.addTextRun(" Print.");
335      }
336      else
337      {
338         p.addTextRun(inCitation.getWebsiteTitle());
339         p.addTextRun(". Web. ");
340         if (inCitation.getAccessDate() != null)
341         {
342            p.addTextRun(sDateFormat.format(inCitation.getAccessDate()));
343            p.addTextRun(".");
344         }
345      }
346
347      return p;
348   }
349
350   //---------------------------------------------------------------------------
351   private String generateSoftwareCitationAsString(Citation inCitation)
352   {
353      return StringUtil.stripHTMLTags(generateSoftwareCitationAsHTML(inCitation).toHTML());
354   }
355   
356   //---------------------------------------------------------------------------
357   private HTMLTag generateSoftwareCitationAsHTML(Citation inCitation)
358   {
359      Span tag = new Span();
360
361      String authorList = generateAuthorListForBibliography(inCitation);
362
363
364      if (StringUtil.isSet(authorList))
365      {
366         tag.addContent(authorList);
367      }
368
369
370      if (StringUtil.isSet(inCitation.getTitle()))
371      {
372         tag.addSpan(inCitation.getTitle()).addStyle(CSS.ITALIC);
373         tag.addContent(".");
374
375         if (StringUtil.isSet(inCitation.getWebsiteTitle())
376               || StringUtil.isSet(inCitation.getURL()))
377         {
378            tag.addContent(" Computer software.");
379         }
380
381         if (StringUtil.isSet(inCitation.getVersion()))
382         {
383            tag.addContent(" Vers. " + inCitation.getVersion() + ".");
384         }
385      }
386
387      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
388      {
389         tag.addContent(" " + inCitation.getPlaceOfPublication() + ":");
390      }
391
392      if (StringUtil.isSet(inCitation.getPublisher()))
393      {
394         tag.addContent(" " + inCitation.getPublisher());
395      }
396
397      if (inCitation.getYear() != null)
398      {
399         tag.addContent(", " + inCitation.getYear() + ".");
400      }
401      else
402      {
403         tag.addContent(".");
404      }
405
406      if (! StringUtil.isSet(inCitation.getWebsiteTitle())
407          && ! StringUtil.isSet(inCitation.getURL()))
408      {
409         tag.addContent(" Computer software.");
410      }
411      else
412      {
413         tag.addContent(inCitation.getWebsiteTitle());
414         tag.addContent(". Web. ");
415         if (inCitation.getAccessDate() != null)
416         {
417            tag.addContent(sDateFormat.format(inCitation.getAccessDate()));
418            tag.addContent(".");
419         }
420      }
421
422      return tag;
423   }
424
425   //---------------------------------------------------------------------------
426   private WmlParagraph generateSoftwareCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
427   {
428      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
429      inParentTag.addSubtag(p);
430
431      String authorList = generateAuthorListForBibliography(inCitation);
432
433      if (StringUtil.isSet(authorList))
434      {
435         p.addTextRun(authorList);
436      }
437
438
439
440      if (StringUtil.isSet(inCitation.getTitle()))
441      {
442         p.addTextRun(inCitation.getTitle()).getProperties().setItalics();
443         p.addTextRun(".");
444
445         if (StringUtil.isSet(inCitation.getWebsiteTitle())
446               || StringUtil.isSet(inCitation.getURL()))
447         {
448            p.addTextRun(" Computer software.");
449         }
450
451         if (StringUtil.isSet(inCitation.getVersion()))
452         {
453            p.addTextRun(" Vers. " + inCitation.getVersion() + ".");
454         }
455      }
456
457      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
458      {
459         p.addTextRun(" " + inCitation.getPlaceOfPublication() + ":");
460      }
461
462      if (StringUtil.isSet(inCitation.getPublisher()))
463      {
464         p.addTextRun(" " + inCitation.getPublisher());
465      }
466
467      if (inCitation.getYear() != null)
468      {
469         p.addTextRun(", " + inCitation.getYear() + ".");
470      }
471      else
472      {
473         p.addTextRun(".");
474      }
475
476      if (! StringUtil.isSet(inCitation.getWebsiteTitle())
477            && ! StringUtil.isSet(inCitation.getURL()))
478      {
479         p.addTextRun(" Computer software.");
480      }
481      else
482      {
483         p.addTextRun(inCitation.getWebsiteTitle());
484         p.addTextRun(". Web. ");
485         if (inCitation.getAccessDate() != null)
486         {
487            p.addTextRun(sDateFormat.format(inCitation.getAccessDate()));
488            p.addTextRun(".");
489         }
490      }
491
492      return p;
493   }
494}