NCBI C++ ToolKit
macro_fn_pubfields.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: macro_fn_pubfields.cpp 47546 2023-08-22 14:54:45Z asztalos $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Andrea Asztalos
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
43 #include <objects/seq/Seqdesc.hpp>
53 
62 
63 /** @addtogroup GUI_MACRO_SCRIPTS_UTIL
64  *
65  * @{
66  */
67 
69 BEGIN_SCOPE(macro)
71 
72 
73 /// class CMacroFunction_PubFields
74 /// PUB_TITLE(), PUB_ISSUE(), PUB_AFFIL(subfield) - returns a list of CObjectInfo (or string) that contain publication title
75 /// subfield is optional, used for affiliation, author or date
76 ///
77 
78 
79 const char* CMacroFunction_PubFields::sm_PubTitle = "PUB_TITLE";
80 const char* CMacroFunction_PubFields::sm_PubAffil = "PUB_AFFIL";
81 const char* CMacroFunction_PubFields::sm_PubAuthors = "PUB_AUTHORS";
82 const char* CMacroFunction_PubFields::sm_PubCit = "PUB_CIT";
83 const char* CMacroFunction_PubFields::sm_PubDate = "PUB_DATE";
84 const char* CMacroFunction_PubFields::sm_PubIssue = "PUB_ISSUE";
85 const char* CMacroFunction_PubFields::sm_PubJournal = "PUB_JOURNAL";
86 const char* CMacroFunction_PubFields::sm_PubPages = "PUB_PAGES";
87 const char* CMacroFunction_PubFields::sm_PubPMID = "PUB_PMID";
88 const char* CMacroFunction_PubFields::sm_PubClass = "PUB_CLASS"; // deprecated, use PUB_STATUS instead
89 const char* CMacroFunction_PubFields::sm_PubStatus = "PUB_STATUS";
90 const char* CMacroFunction_PubFields::sm_PubSerialNumber = "PUB_SERIAL_NUMBER";
91 const char* CMacroFunction_PubFields::sm_PubVolume = "PUB_VOLUME";
92 
94  : IEditMacroFunction(func_scope), m_FieldType(field), m_ResField(kEmptyStr)
95 {
96 }
97 
98 bool CMacroFunction_PubFields::s_IsPubFieldFnc(const string& fn_name)
99 {
100  static vector<string> pub_fncs{ sm_PubTitle, sm_PubAffil, sm_PubAuthors, sm_PubCit, sm_PubDate,
103  };
104 
105  auto it = find_if(pub_fncs.begin(), pub_fncs.end(),
106  [&fn_name](const auto& elem) { return NStr::EqualNocase(fn_name, elem); });
107  return (it != pub_fncs.end());
108 }
109 
111 {
112  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
113  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
114  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
115 
116 
117  CObjectInfo oi = m_DataIter->GetEditedObject();
118  CMQueryNodeValue::TObs res_oi;
119  if (const_pubdesc) {
120  if (!GetFieldsByName(&res_oi, oi, "pub..") || res_oi.size() != 1) {
121  return;
122  }
123  }
124  else if (const_block) {
126  CObjectInfo parent;
127  CObjectInfo block_oi(submit_block, submit_block->GetThisTypeInfo());
128  res_oi.push_back(CMQueryNodeValue::SResolvedField(parent, block_oi));
129  }
130 
131  if (res_oi.empty()) { // when iterator is not Pubdesc
132  CBioseq_Handle bsh = m_DataIter->GetBioseqHandle();
133  vector<string> statuses;
134  for (CSeqdesc_CI desc_it(bsh, CSeqdesc::e_Pub); desc_it; ++desc_it) {
135  const CPubdesc& c_pubdesc = desc_it->GetPub();
136  CPubdesc& pubdesc = const_cast<CPubdesc&>(c_pubdesc);
137  CObjectInfo pub_oi(&pubdesc, pubdesc.GetThisTypeInfo());
138  GetFieldsByName(&res_oi, pub_oi, "pub..");
140  string status = x_GetPubStatus(oi);
141  statuses.push_back(status);
142  }
143  }
144 
147  new_node->SetStrings(statuses);
148  m_Result->SetRef(new_node);
149  return;
150  }
151  }
152 
153  if (res_oi.empty()) {
154  return;
155  }
156 
157  m_ResField = (m_Args.size() == 1) ? m_Args[0]->GetString() : kEmptyStr;
158 
160  if (const_pubdesc) {
162  // on-the-fly variable, derived from a combination of the status and the type of pub
163  string status = x_GetPubStatus(oi);
165  new_node->SetString(status);
166  m_Result->SetRef(new_node);
167  return;
168  }
169  // res_oi should be a container of pointers, each of them pointing to a Pub field
170  CObjectInfoEI elem = res_oi.front().field.BeginElements();
171  while (elem.Valid()) {
172  CObjectInfo pub(elem.GetElement().GetPointedObject()); // the Pub field
173  x_GetPubFieldObjectFromPub(pub, objs);
174  ++elem;
175  }
176  }
177  else if (const_block) {
181  new_node->SetString(status);
182  m_Result->SetRef(new_node);
183  // if it's not returned as a reference node, this can not be passed as an argument to the
184  // string constraint functions
185  return;
186  }
187  else {
188  x_GetPubFieldObjectFromSubmitBlock(res_oi.front().field, objs);
189  }
190  }
191  else { // when iterator is not Pubdesc
192  for (auto&& it : res_oi) {
193  CObjectInfoEI elem = it.field.BeginElements();
194  while (elem.Valid()) {
195  CObjectInfo pub(elem.GetElement().GetPointedObject()); // the Pub field
196  x_GetPubFieldObjectFromPub(pub, objs);
197  ++elem;
198  }
199  }
200  }
201 
202  if (objs.empty())
203  return;
204  if (m_Nested == eNotNested) { // return a standard type value
205  m_Result->AssignFromObjectInfo(objs.front().field); // for now, return only one value
206  }
207  else {
208  m_Result->SetObjects(objs);
209  }
210 }
211 
213 {
214  ITERATE(CMQueryNodeValue::TObs, it, objs_from) {
215  objs_to.push_back(*it);
216  }
217 }
218 
220 {
222  return;
223 
224  if (pub.Which() == CPub::e_Gen) {
225  CObjectInfoMI mem = pub_var.FindClassMember("cit");
226  if (mem.IsSet()) {
227  objs.push_back(CMQueryNodeValue::SResolvedField(pub_var, mem.GetMember()));
228  }
229  }
230 }
231 
233 {
235  return;
236 
237  switch (pub.Which()) {
238  case (CPub::e_Gen):
239  case (CPub::e_Patent):{
240  CObjectInfoMI mem = pub_var.FindClassMember("title");
241  if (mem.IsSet()) {
242  objs.push_back(CMQueryNodeValue::SResolvedField(pub_var, mem.GetMember()));
243  }
244  break;
245  }
246  case (CPub::e_Sub): {
247  CObjectInfoMI mem = pub_var.FindClassMember("descr");
248  if (mem.IsSet()) {
249  objs.push_back(CMQueryNodeValue::SResolvedField(pub_var, mem.GetMember()));
250  }
251  break;
252  }
253  case (CPub::e_Article):
254  case (CPub::e_Book):
255  case (CPub::e_Man): {
256  CObjectInfo book_oi = pub_var;
257  if (pub.IsMan()) {
258  CObjectInfoMI mem = pub_var.FindClassMember("cit");
259  if (mem.IsSet()) {
260  book_oi = mem.GetMember();
261  if (book_oi.GetTypeFamily() == eTypeFamilyPointer) {
262  book_oi = book_oi.GetPointedObject();
263  }
264  }
265  }
266 
267  CObjectInfoMI mem = book_oi.FindClassMember("title");
268  if (mem.IsSet() && mem.GetMember().GetTypeFamily() == eTypeFamilyPointer) {
270  } else {
271  // not set
272  //NcbiCout << "Member not set or member is not pointer type" << NcbiEndl;
273  }
274  break;
275  }
276  default:
277  break;
278  }
279 }
280 
282 {
284  return;
285 
286  switch (pub.Which()) {
287  case (CPub::e_Gen): {
288  CObjectInfoMI mem = pub_var.FindClassMember("serial-number");
289  if (mem.IsSet()) {
290  objs.push_back(CMQueryNodeValue::SResolvedField(pub_var, mem.GetMember()));
291  }
292  break;
293  }
294  default:
295  break;
296  }
297 }
298 
300 {
302  return;
303 
304  switch (pub.Which()) {
305  case (CPub::e_Gen): {
306  CObjectInfoMI mem = pub_var.FindClassMember("journal");
307  if (mem.IsSet() && mem.GetMember().GetTypeFamily() == eTypeFamilyPointer) {
309  } else {
310  //NcbiCout << "Member not set or member is not pointer type" << NcbiEndl;
311  }
312  break;
313  }
314  case (CPub::e_Article):
315  case (CPub::e_Journal): {
316  CObjectInfo jour_oi = pub_var;
317  if (pub.IsArticle() && pub.GetArticle().IsSetFrom() && pub.GetArticle().GetFrom().IsJournal()) {
318  const CCit_jour& const_journal = pub.GetArticle().GetFrom().GetJournal();
319  CCit_jour& journal = const_cast<CCit_jour&> (const_journal);
320  CObjectInfo oi(&journal, journal.GetTypeInfo());
321  jour_oi = oi;
322  }
323 
324  CObjectInfoMI mem = jour_oi.FindClassMember("title");
325  if (mem.IsSet() && mem.GetMember().GetTypeFamily() == eTypeFamilyPointer) {
327  } else {
328  // not set
329  //NcbiCout << "Member not set or member is not pointer type" << NcbiEndl;
330  }
331  break;
332  }
333  default:
334  break;
335  }
336 }
337 
338 static CObjectInfo s_GetRelevantObjectInfoForPub(const CPub& pub, const CObjectInfo& pub_var)
339 {
340  CObjectInfo oi = pub_var;
341  if (pub.IsArticle() && pub.GetArticle().IsSetFrom()) {
342  const CCit_art& article = pub.GetArticle();
343 
344  if (article.GetFrom().IsJournal()) {
345  const CCit_jour& const_journal = article.GetFrom().GetJournal();
346  CCit_jour& journal = const_cast<CCit_jour&> (const_journal);
347  CObjectInfo jour_oi(&journal, journal.GetTypeInfo());
348  oi = jour_oi;
349  }
350  else if (article.GetFrom().IsBook()) {
351  const CCit_book& const_book = article.GetFrom().GetBook();
352  CCit_book& book = const_cast<CCit_book&> (const_book);
353  CObjectInfo book_oi(&book, book.GetTypeInfo());
354  oi = book_oi;
355  }
356  else if (article.GetFrom().IsProc()) {
357  const CCit_book& const_book = article.GetFrom().GetProc().GetBook();
358  CCit_book& book = const_cast<CCit_book&> (const_book);
359  CObjectInfo book_oi(&book, book.GetTypeInfo());
360  oi = book_oi;
361  }
362  }
363  else if (pub.IsMan()) {
364  CObjectInfoMI mem = pub_var.FindClassMember("cit");
365  if (mem.IsSet()) {
366  oi = mem.GetMember();
367  }
368  }
369  return oi;
370 }
371 
373 {
375  return;
376 
377  switch (pub.Which()) {
378  case (CPub::e_Gen):
379  case (CPub::e_Sub): {
380  CObjectInfoMI mem = pub_var.FindClassMember("date");
381  if (mem.Valid() && mem.GetMember().GetTypeFamily() == eTypeFamilyPointer) {
383  }
384  break;
385  }
386  case (CPub::e_Article):
387  case (CPub::e_Book):
388  case (CPub::e_Man):
389  case (CPub::e_Journal): {
390  CObjectInfo oi = s_GetRelevantObjectInfoForPub(pub, pub_var);
391 
393  if (GetFieldsByName(&res, oi, "imp.date") && res.size() == 1) {
394  CObjectInfo date = res.front().field;
395  if (date.GetTypeFamily() == eTypeFamilyPointer) {
397  }
398  }
399  break;
400  }
401  default:
402  break;
403  }
404 }
405 
407 {
408  string field_name = kEmptyStr;
409  switch (m_FieldType) {
411  field_name.assign("volume");
412  break;
414  field_name.assign("issue");
415  break;
417  field_name.assign("pages");
418  break;
419  default:
420  return;
421  }
422 
423  if (NStr::IsBlank(field_name))
424  return;
425 
426  switch (pub.Which()) {
427  case (CPub::e_Gen): {
428  CObjectInfoMI mem = pub_var.FindClassMember(field_name);
429  if (mem.IsSet()) {
430  objs.push_back(CMQueryNodeValue::SResolvedField(pub_var, mem.GetMember()));
431  }
432  break;
433  }
434  case (CPub::e_Article):
435  case (CPub::e_Book):
436  case (CPub::e_Man):
437  case (CPub::e_Journal): {
438  CObjectInfo oi = s_GetRelevantObjectInfoForPub(pub, pub_var);
439  if (oi.GetTypeFamily() == eTypeFamilyPointer) {
440  oi = oi.GetPointedObject();
441  }
442 
443  CObjectInfoMI mem = oi.FindClassMember("imp");
444  s_GetObjectsFromImprint(mem.GetMember(), field_name, objs);
445  break;
446  }
447  default:
448  break;
449  }
450 }
451 
453 {
455  return;
456 
457  switch (pub.Which()) {
458  case (CPub::e_Gen):
459  case (CPub::e_Sub):
460  case (CPub::e_Article):
461  case (CPub::e_Book):
462  case (CPub::e_Patent):
463  case (CPub::e_Man): {
464  CObjectInfo oi = pub_var;
465  if (pub.IsMan()) {
466  CObjectInfoMI mem = pub_var.FindClassMember("cit");
467  if (mem.IsSet()) {
468  oi = mem.GetMember();
469  }
470  }
471 
473  if (GetFieldsByName(&res, oi, "authors.affil") && res.size() == 1) {
474  CObjectInfo affil = res.front().field;
475  if (affil.GetTypeFamily() == eTypeFamilyPointer) {
476  CObjectInfo affil_oi = affil.GetPointedObject();
477  s_GetObjectsFromAffil(affil_oi, m_ResField, objs);
478  }
479  }
480  break;
481  }
482  default:
483  break;
484  }
485 
486 }
487 
489 {
491  return;
492 
493  switch (pub.Which()) {
494  case (CPub::e_Gen):
495  case (CPub::e_Sub):
496  case (CPub::e_Article):
497  case (CPub::e_Book):
498  case (CPub::e_Patent):
499  case (CPub::e_Man): {
500  CObjectInfo oi = pub_var;
501  if (pub.IsMan()) {
502  CObjectInfoMI mem = pub_var.FindClassMember("cit");
503  if (mem.IsSet()) {
504  oi = mem.GetMember();
505  }
506  }
507 
509  if (GetFieldsByName(&res, oi, "authors.names") && res.size() == 1) {
510  CObjectInfo affil = res.front().field;
511  if (affil.GetTypeFamily() == eTypeFamilyPointer) {
513  }
514  }
515  break;
516  }
517  default:
518  break;
519  }
520 
521 }
522 
524 {
526  return;
527  if (pub.IsPmid() && pub_var.GetTypeFamily() == eTypeFamilyPointer) {
528  CObjectInfo parent_oi(&pub, pub.GetTypeInfo());
529  objs.push_back(CMQueryNodeValue::SResolvedField(parent_oi, pub_var.GetPointedObject()));
530  }
531 }
532 
534 {
535  const CPubdesc* pubdesc = CTypeConverter<CPubdesc>::SafeCast(pubdesc_oi.GetObjectPtr());
536  if (!pubdesc) {
537  return kEmptyStr;
538  }
539  return s_GetStatus(*pubdesc);
540 }
541 
543 {
544  string rval;
545  if (pdesc.IsSetPub()) {
546  for (auto&& it: pdesc.GetPub().Get()) {
547  rval = x_GetStatus(*it);
548  if (!rval.empty()) {
549  break;
550  }
551  }
552  }
553  return rval;
554 }
555 
557 {
559  if (status != CPubFieldType::ePubFieldStatus_Any) {
560  return CPubFieldType::GetLabelForStatus(status);
561  }
562  return kEmptyStr;
563 }
564 
566 {
568  switch (pub.Which()) {
569  case CPub::e_Gen:
570  if (pub.GetGen().IsSetCit() && s_IsUnpublished(pub.GetGen().GetCit())) {
572  }
573  else {
575  }
576  break;
577  case CPub::e_Sub:
579  break;
580  case CPub::e_Patent:
581  case CPub::e_Pmid:
583  break;
584  default:
585  {{
588  if (imp) {
589  if (imp->IsSetPrepub()) {
590  if (imp->GetPrepub() == CImprint::ePrepub_in_press) {
592  }
593  else {
595  }
596  }
597  else {
599  }
600  }
601  }}
602  break;
603 
604  }
605 
606  return status;
607 }
608 
609 bool CMacroFunction_PubFields::s_IsUnpublished(const string& citation)
610 {
611  return (NStr::StartsWith(citation, "unpublished", NStr::eNocase) ||
612  NStr::StartsWith(citation, "submitted", NStr::eNocase) ||
613  NStr::StartsWith(citation, "Online Publication", NStr::eNocase) ||
614  NStr::StartsWith(citation, "Published Only in Database", NStr::eNocase) ||
615  NStr::StartsWith(citation, "(er)", NStr::eNocase));
616 }
617 
618 
620 {
621  // fields from the class CDate
622  if (!date || NStr::IsBlank(field_name))
623  return;
624 
625  if (date.GetCurrentChoiceVariantIndex() == 1) { // str
626  CObjectInfo date_oi = date.GetCurrentChoiceVariant().GetVariant();
627  objs.push_back(CMQueryNodeValue::SResolvedField(date, date_oi));
628  } else if (date.GetCurrentChoiceVariantIndex() == 2) { // std
629  CObjectInfo date_std = date.GetCurrentChoiceVariant().GetVariant();
631  if (GetFieldsByName(&res, date_std, field_name)) {
632  s_CopyResolvedObjs(res, objs);
633  }
634  }
635 }
636 
637 void CMacroFunction_PubFields::s_GetObjectsFromAffil(const CObjectInfo& affil, const string& field_name, CMQueryNodeValue::TObs& objs)
638 {
639  // resolving field from class CAffil
640  if (!affil)
641  return;
642 
643  if (NStr::IsBlank(field_name)) {
644  objs.push_back(CMQueryNodeValue::SResolvedField(CObjectInfo(), affil));
645  return;
646  }
647 
648  if (affil.GetCurrentChoiceVariantIndex() == 1) { // str
649  CObjectInfo affil_str = affil.GetCurrentChoiceVariant().GetVariant();
650  objs.push_back(CMQueryNodeValue::SResolvedField(affil, affil_str));
651  } else if (affil.GetCurrentChoiceVariantIndex() == 2) { // std
652  CObjectInfo affil_std = affil.GetCurrentChoiceVariant().GetVariant();
654  if (GetFieldsByName(&res, affil_std, field_name)) {
655  s_CopyResolvedObjs(res, objs);
656  }
657  }
658 }
659 
661 {
662  CObjectInfo var = names.GetCurrentChoiceVariant().GetVariant();
663  string var_name = names.GetCurrentChoiceVariant().GetVariantInfo()->GetId().GetName();
664  switch (names.GetCurrentChoiceVariantIndex()) {
665  case (1): // dbtag
666  objs.push_back(CMQueryNodeValue::SResolvedField(names, var)); // returns a Dbtag object
667  break;
668  case (2): { // name
669  if (field_name.empty()) {
670  objs.push_back(CMQueryNodeValue::SResolvedField(names, var));
671  }
672  else {
674  if (GetFieldsByName(&res, var, field_name)) {
675  s_CopyResolvedObjs(res, objs);
676  }
677  }
678  break;
679  }
680  case (5): // consortium
681  if (NStr::EndsWith(field_name, var_name)) {
682  objs.push_back(CMQueryNodeValue::SResolvedField(names, var));
683  }
684  break;
685  default:
686  break;
687  }
688 }
689 
691 {
692  // resolving field from Auth_list.names
693  if (names.GetCurrentChoiceVariantIndex() == 1) { // std - container of pointers to Authors
694  CObjectInfo names_std = names.GetCurrentChoiceVariant().GetVariant();
695  if (names_std.GetTypeFamily() == eTypeFamilyContainer) {
696  CObjectInfoEI elem = names_std.BeginElements();
697  while (elem.Valid()) {
698  CObjectInfo elem_oi(elem.GetElement().GetPointedObject()); // an Author object
699  CObjectInfoMI mem = elem_oi.FindClassMember("name");
700  if (mem.IsSet()) {
701  s_GetObjectsFromPersonID(mem.GetMember().GetPointedObject(), field_name, objs);
702  }
703  ++elem;
704  }
705  }
706  } else if (names.GetCurrentChoiceVariantIndex() == 3) { // str - container of strings
707  CObjectInfo names_str = names.GetCurrentChoiceVariant().GetVariant();
708  if (names_str.GetTypeFamily() == eTypeFamilyContainer) {
709  CObjectInfoEI elem = names_str.BeginElements();
710  while (elem.Valid()) {
711  objs.push_back(CMQueryNodeValue::SResolvedField(names_str, elem.GetElement()));
712  ++elem;
713  }
714  }
715  }
716 }
717 
719 {
720  if (!title)
721  return;
722 
723  // Title is a class with its first member being a container of pointers of choice
724  CObjectInfoMI mem = title.BeginMembers();
725  while (mem.Valid() && mem.IsSet()) {
726  CObjectInfo mem_oi = mem.GetMember(); // should be a container
727  if (mem_oi.GetTypeFamily() == eTypeFamilyContainer) {
728  CObjectInfoEI elem = mem_oi.BeginElements();
729  while (elem.Valid()) {
730  CObjectInfo elem_oi(elem.GetElement().GetPointedObject());
731  CObjectInfoCV var = elem_oi.GetCurrentChoiceVariant();
732  CObjectInfo pub_var = var.GetVariant(); // should be a primitive
733  objs.push_back(CMQueryNodeValue::SResolvedField(elem_oi, pub_var));
734 
735  ++elem;
736  }
737  }
738  ++mem;
739  }
740 }
741 
742 
744 {
745  if (NStr::IsBlank(field_name))
746  return;
747 
749  if (GetFieldsByName(&res, imp, field_name)) {
750  s_CopyResolvedObjs(res, objs);
751  }
752 }
753 
755 {
757  if (!pub)
758  return;
759 
760  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
761 
762  switch (m_FieldType) {
763  case (ePublication_field_cit):
764  x_GetObjectsForPubField_Cit(*pub, pub_var, objs);
765  break;
767  x_GetObjectsForPubField_Title(*pub, pub_var, objs);
768  break;
770  x_GetObjectsForPubField_SerialNumber(*pub, pub_var, objs);
771  break;
773  x_GetObjectsForPubField_Journal(*pub, pub_var, objs);
774  break;
778  x_GetObjectsForPubField_VolIssuePage(*pub, pub_var, objs);
780  x_GetObjectsForPubField_Date(*pub, pub_var, objs);
781  break;
783  x_GetObjectsForPubField_AffilField(*pub, pub_var, objs);
784  break;
786  x_GetObjectsForPubField_PMID(*pub, pub_var, objs);
787  break;
789  x_GetObjectsForPubField_Authors(*pub, pub_var, objs);
790  break;
791  default:
792  break;
793  }
794 }
795 
797 {
798  CObjectInfo sub_oi = block_oi.FindClassMember("cit").GetMember();
799  if (sub_oi.GetTypeFamily() == eTypeFamilyPointer) {
800  sub_oi = sub_oi.GetPointedObject();
801  }
802 
803  switch (m_FieldType) {
805  {
806  CObjectInfoMI mem = sub_oi.FindClassMember("descr");
807  if (mem.IsSet()) {
808  objs.push_back(CMQueryNodeValue::SResolvedField(sub_oi, mem.GetMember()));
809  }
810  break;
811  }
812  case (ePublication_field_cit):
816  // not relevant
817  break;
819  m_ResField = "volume";
821  m_ResField = "issue";
823  {
824  m_ResField = "pages";
825 
826  CObjectInfoMI mem = sub_oi.FindClassMember("imp");
827  if (mem.IsSet()) {
829  }
830  break;
831  }
833  {
834  CObjectInfoMI mem = sub_oi.FindClassMember("date");
835  if (mem.Valid() && mem.GetMember().GetTypeFamily() == eTypeFamilyPointer) {
837  }
838  break;
839  }
841  {
843  if (GetFieldsByName(&res, sub_oi, "authors.affil") && res.size() == 1) {
844  CObjectInfo affil = res.front().field;
845  if (affil.GetTypeFamily() == eTypeFamilyPointer) {
846  CObjectInfo affil_oi = affil.GetPointedObject();
847  s_GetObjectsFromAffil(affil_oi, m_ResField, objs);
848  }
849  }
850  break;
851  }
853  {
855  if (GetFieldsByName(&res, sub_oi, "authors.names") && res.size() == 1) {
856  CObjectInfo affil = res.front().field;
857  if (affil.GetTypeFamily() == eTypeFamilyPointer) {
859  }
860  }
861  }
862  default:
863  break;
864  }
865 }
866 
868 {
869  return (m_Args.empty() || (m_Args.size() == 1 && m_Args[0]->IsString()));
870 }
871 
872 ///////////////////////////////////////////////////////////////////////////////
873 /// class CMacroFunction_ApplyPublication
874 /// SetPub_Sub(author_field_name, author_field_value)
875 /// Apply new publication to the sequence
876 ///
877 const char* CMacroFunction_ApplyPublication::sm_FunctionName = "SetPub_Sub";
879 {
880  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
881  CRef<CScope> scope = m_DataIter->GetScopedObject().scope;
882  const CBioseq* bseq = dynamic_cast<const CBioseq*>(obj.GetPointer());
883  if (!bseq || !scope)
884  return;
885 
886  const string& author_field = m_Args[0]->GetString();
887  CMQueryNodeValue& new_value = m_Args[1].GetNCObject();
888 
889  CRef<CPub> new_pub(new CPub());
890  new_pub->Select(m_PubType);
891 
892  CObjectInfo oi;
893  switch (m_PubType) {
894  case CPub::e_Sub: {
895  CCit_sub& cit_sub = new_pub->SetSub();
896  oi = ObjectInfo(cit_sub);
897  break;
898  }
899  default:
900  // for now it only handles cit-sub types
901  break;
902  }
903 
904  CMQueryNodeValue::TObs res_oi;
905  if (!SetFieldsByName(&res_oi, oi, author_field)) {
906  return;
907  }
908 
910  if (SetSimpleTypeValue(it->field, new_value)) {
912  }
913  }
914 
915  CRef<CSeqdesc> new_desc(new CSeqdesc());
916  new_desc->SetPub().SetPub().Set().push_back(new_pub);
917 
918  CBioseq_Handle bsh = scope->GetBioseqHandle(*bseq);
921  if (bssh && bssh.IsSetClass() && bssh.GetClass() == CBioseq_set::eClass_nuc_prot) {
922  seh = bssh.GetParentEntry();
923  }
924  CRef<CCmdCreateDesc> create_cmd(new CCmdCreateDesc(seh, *new_desc));
925 
926  CRef<CCmdComposite> cmd(new CCmdComposite("Create new publication"));
927  cmd->AddCommand(*create_cmd);
928  m_DataIter->RunCommand(cmd, m_CmdComposite);
929 
931  log << m_DataIter->GetBestDescr() << ": added new publication";
933 }
934 
936 {
937  return (m_Args.size() == 2 && m_Args[0]->IsString() && m_Args[1]->IsString());
938 }
939 
940 
941 ///////////////////////////////////////////////////////////////////////////////
942 /// class CMacroFunction_AuthorFix
943 /// MoveMiddleToFirstName(); - moves middle name to first name and fixes the initials
944 /// RemoveAuthorSuffix(); - removes author suffix
945 /// TruncateMiddleInitials(); - truncates middle name initials
946 /// ReverseAuthorNames() - swaps the first and the last name
947 
952 
956  { "Move middle name to first", CMacroFunction_AuthorFix::eMoveMiddleName },
957  { "Remove author suffix", CMacroFunction_AuthorFix::eStripSuffix },
958  { "Reverse author names", CMacroFunction_AuthorFix::eReverseNames},
959  { "Truncate middle initials", CMacroFunction_AuthorFix::eTruncateMI },
960 };
961 
964 
966 {
967  TAuthorFixTypeMap::const_iterator iter = sm_AuthorFixMap.begin();
968  for (; iter != sm_AuthorFixMap.end(); ++iter){
969  if (iter->second == fix_type){
970  return iter->first;
971  }
972  }
973  return kEmptyStr;
974 }
975 
977 {
978  TAuthorFixTypeMap::const_iterator iter = sm_AuthorFixMap.find(descr);
979  if (iter != sm_AuthorFixMap.end()){
980  return iter->second;
981  }
983 }
984 
986 {
987  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
988  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
989  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
990 
991  int count = 0;
992  if (const_pubdesc) {
993  CObjectInfo oi = m_DataIter->GetEditedObject();
995 
996  EDIT_EACH_PUB_ON_PUBEQUIV(it, pubdesc->SetPub()) {
997  CPub& pub = **it;
998  CAuth_list* authors = 0;
999  switch (pub.Which()) {
1000  case CPub::e_Gen:
1001  if (pub.GetGen().IsSetAuthors()) {
1002  authors = &(pub.SetGen().SetAuthors());
1003  }
1004  break;
1005  case CPub::e_Sub:
1006  authors = &(pub.SetSub().SetAuthors());
1007  break;
1008  case CPub::e_Article:
1009  if (pub.GetArticle().IsSetAuthors()) {
1010  authors = &(pub.SetArticle().SetAuthors());
1011  }
1012  break;
1013  case CPub::e_Book:
1014  authors = &(pub.SetBook().SetAuthors());
1015  break;
1016  case CPub::e_Proc:
1017  authors = &(pub.SetProc().SetBook().SetAuthors());
1018  break;
1019  case CPub::e_Man:
1020  authors = &(pub.SetMan().SetCit().SetAuthors());
1021  break;
1022  case CPub::e_Patent:
1023  authors = &(pub.SetPatent().SetAuthors());
1024  break;
1025  default:
1026  break;
1027  }
1028  if (!authors)
1029  continue;
1030 
1031  count += x_MakeAuthorChanges(*authors);
1032  }
1033  }
1034  else if (const_block) {
1035  CObjectInfo oi = m_DataIter->GetEditedObject();
1037 
1038  if (submit_block->IsSetCit() && submit_block->GetCit().IsSetAuthors()) {
1039  CAuth_list& authors = submit_block->SetCit().SetAuthors();
1040  count = x_MakeAuthorChanges(authors);
1041  }
1042 
1043  // don't apply to Contact-info
1044  }
1045 
1046  if (count > 0) {
1047  m_DataIter->SetModified();
1049  log << m_DataIter->GetBestDescr() << ": " << GetDescription(m_FixType) << " for " << count << " names";
1050  x_LogFunction(log);
1051  }
1052 }
1053 
1055 {
1056  if (!auth_list.IsSetNames())
1057  return 0;
1058  CAuth_list::TNames& names = auth_list.SetNames();
1059  if (!names.IsStd())
1060  return 0;
1061 
1062  int count = 0;
1063  NON_CONST_ITERATE(list<CRef<CAuthor> >, it, names.SetStd()) {
1064  CAuthor& auth = **it;
1065  CPerson_id& person = auth.SetName();
1066  if (!person.IsName())
1067  continue;
1068  CName_std& std_name = person.SetName();
1069 
1070  switch (m_FixType) {
1071  case (eMoveMiddleName) :
1072  if (s_MoveMiddleToFirst(std_name)) {
1073  count++;
1074  }
1075  break;
1076  case (eStripSuffix) :
1077  if (std_name.IsSetSuffix()) {
1078  std_name.ResetSuffix();
1079  count++;
1080  }
1081  break;
1082  case (eReverseNames):
1083  if (s_ReverseAuthorNames(std_name)) {
1084  count++;
1085  }
1086  break;
1087  case (eTruncateMI) :
1088  if (s_TruncateMiddleInitials(std_name)) {
1089  count++;
1090  }
1091  break;
1092  default:
1093  break;
1094  }
1095  }
1096  return count;
1097 }
1098 
1100 {
1101  if (!name.IsSetInitials())
1102  return false;
1103 
1104  // return if the initials field contains exactly the first name initials
1105  if (name.IsSetFirst() && NStr::EqualCase(name.GetInitials(), s_GetFirstNameInitials(name.GetFirst()))) {
1106  return false;
1107  }
1108 
1109  string first_name = (name.IsSetFirst()) ? name.GetFirst() : kEmptyStr;
1110  string initials = name.GetInitials();
1111  string first_name_initial = s_GetFirstNameInitialsWithoutStops(first_name);
1112 
1113  vector<string> names;
1114  NStr::Split(initials, ".", names);
1115  vector<string>::iterator it = names.begin();
1116  while (it != names.end()) {
1117  if ((!first_name_initial.empty() && NStr::EqualCase(*it, first_name_initial)) ||
1118  it->length() <= 2) {
1119  it = names.erase(it);
1120  }
1121  else {
1122  ++it;
1123  }
1124  }
1125 
1126  for (auto& it : names) {
1127  if (!first_name.empty()) {
1128  first_name += " ";
1129  }
1130  first_name += it;
1131  }
1132 
1133  if (first_name.empty() ||
1134  (name.IsSetFirst() && NStr::EqualCase(first_name, name.GetFirst()))) {
1135  return false;
1136  }
1137 
1138  name.SetFirst(first_name);
1140  return true;
1141 }
1142 
1144 {
1145  if (!name.IsSetInitials())
1146  return false;
1147 
1148  string first_init;
1149  if (name.IsSetFirst()) {
1150  first_init = s_GetFirstNameInitials(name.GetFirst());
1151  }
1152 
1153  string new_middle_init;
1154  string original_init = name.GetInitials();
1155  // when the initials already contain the first name initials
1156  if (!first_init.empty() && NStr::StartsWith(original_init, first_init, NStr::eCase)) {
1157  string middle_init = original_init.substr(first_init.length());
1158  if (!middle_init.empty()) {
1159  new_middle_init = edit::GetFirstInitial(middle_init, false);
1160  }
1161  }
1162  else {
1163  // assume the initials field contains middle name/initials only
1164  new_middle_init = s_GetFirstNameInitials(original_init);
1165  }
1166 
1167  if (!new_middle_init.empty()) {
1168  name.SetInitials(first_init + new_middle_init);
1169  return true;
1170  }
1171 
1172  return false;
1173 }
1174 
1176 {
1177  if (!name.IsSetInitials())
1178  return false;
1179 
1180  string first_init;
1181  if (name.IsSetFirst()) {
1182  first_init = s_GetFirstNameInitials(name.GetFirst());
1183  }
1184 
1185  string original_init = name.GetInitials();
1186  string middle_init;
1187  if (!first_init.empty() && NStr::StartsWith(original_init, first_init, NStr::eCase)) {
1188  middle_init = original_init.substr(first_init.length());
1189  if (!middle_init.empty()) {
1190  middle_init = edit::GetFirstInitial(middle_init, false);
1191  }
1192  }
1193  else {
1194  // assume the initials field contains middle name/initials only
1195  middle_init = s_GetFirstNameInitials(original_init);
1196  }
1197 
1198  string new_initials = first_init + middle_init;
1199  if (!NStr::EqualCase(new_initials, name.GetInitials())) {
1200  name.SetInitials(new_initials);
1201  return true;
1202  }
1203 
1204  return false;
1205 }
1206 
1208 {
1209  string inits = s_GetFirstNameInitialsWithoutStops(first_name);
1210  inits = s_InsertInitialPeriods(inits);
1211  return inits;
1212 }
1213 
1215 {
1216  char buf[2];
1217 
1218  string inits = "";
1219  buf[1] = 0;
1220 
1221  string::const_iterator p = orig.begin();
1222  while (p != orig.end()) {
1223  string::const_iterator q = p;
1224  q++;
1225  buf[0] = *p;
1226  inits.append(buf);
1227  if (isalpha(*p) && (q == orig.end() || (*q != '.' && !islower(*q)))) {
1228  inits.append(".");
1229  }
1230  p++;
1231  }
1232 
1233  return inits;
1234 }
1235 
1237 {
1238  char buf[2];
1239 
1240  string inits = "";
1241  buf[1] = 0;
1242 
1243  string::const_iterator p = first_name.begin();
1244  while (p != first_name.end()) {
1245  // skip leading punct
1246  while (p != first_name.end() && (*p <= ' ' || *p == '-')) {
1247  p++;
1248  }
1249  if (p != first_name.end() && isalpha(*p)) {
1250  buf[0] = *p;
1251  inits.append(buf);
1252  p++;
1253  }
1254  // skip rest of name
1255  while (p != first_name.end() && *p > ' ' && *p != '-') {
1256  p++;
1257  }
1258  if (p != first_name.end() && *p == '-') {
1259  buf[0] = *p;
1260  inits.append(buf);
1261  p++;
1262  }
1263  }
1264  return inits;
1265 }
1266 
1268 {
1269  bool modified = false;
1270  if (name.IsSetLast() && name.IsSetFirst() && !name.GetLast().empty() && !name.GetFirst().empty()) {
1271  string last = name.GetLast();
1272  string first = name.GetFirst();
1273  name.SetLast(first);
1274  name.SetFirst(last);
1275  if (name.IsSetInitials()) {
1276  string initials = name.GetInitials();
1277  string first_init = s_GetFirstNameInitials(first);
1278  string middle_init = initials;
1279  if (!first_init.empty() && NStr::StartsWith(initials, first_init, NStr::eNocase))
1280  middle_init = middle_init.substr(first_init.length());
1281 
1282  string new_init = s_GetFirstNameInitials(last) + middle_init;
1283  name.SetInitials(new_init);
1284  }
1285  s_FixInitials(name);
1286  modified = true;
1287  }
1288  return modified;
1289 }
1290 
1291 void CMacroFunction_AuthorFix::s_BuildName(const string& firstname, const string& mid_initials,
1292  const string& lastname, const string& suffix, CName_std& name)
1293 {
1294  if (NStr::IsBlank(firstname)) {
1295  name.ResetFirst();
1296  }
1297  else {
1298  name.SetFirst(firstname);
1299  }
1300 
1301  if (NStr::IsBlank(lastname)) {
1302  name.ResetLast();
1303  }
1304  else {
1305  name.SetLast(lastname);
1306  }
1307 
1308  // need to do parsing for middle initial
1309  if (NStr::IsBlank(firstname)) {
1310  if (!NStr::IsBlank(mid_initials)) {
1311  name.SetFirst(mid_initials);
1312  }
1313  name.ResetInitials();
1314  }
1315  else {
1316  string inits = macro::CMacroFunction_AuthorFix::s_GetFirstNameInitials(name.GetFirst());
1317  if (!NStr::IsBlank(mid_initials)) {
1318  inits.append(mid_initials);
1319  }
1320  // don't add another period if one is already there
1321  if (!NStr::EndsWith(inits, ".")) {
1322  inits.append(".");
1323  }
1324  name.SetInitials(inits);
1325  }
1326 
1328 
1329  // suffix
1330  if (NStr::IsBlank(suffix)) {
1331  name.ResetSuffix();
1332  }
1333  else {
1334  name.SetSuffix(suffix.c_str());
1335  }
1336 }
1337 
1339 {
1340  return m_Args.empty();
1341 }
1342 
1343 ///////////////////////////////////////////////////////////////////////////////
1344 /// class CMacroFunction_ISOJTALookup
1345 /// ISOJTALookup();
1346 ///
1349 {
1350  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
1351  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(obj.GetPointer());
1352  if (!const_pubdesc) {
1353  return;
1354  }
1355 
1356  // look for an article
1357  CObjectInfo oi = m_DataIter->GetEditedObject();
1359  if (!pubdesc) {
1360  return;
1361  }
1362 
1363  m_Hits.clear();
1364  m_TitlePairs.clear();
1365  if (pubdesc->IsSetPub() && pubdesc->GetPub().IsSet()) {
1366  for (auto&& it : pubdesc->SetPub().Set()) {
1367  if (it->IsArticle()
1368  && it->GetArticle().IsSetFrom()
1369  && it->GetArticle().GetFrom().IsJournal()) {
1370  x_LookupTitleInJournal(it->SetArticle().SetFrom().SetJournal());
1371  }
1372  }
1373  }
1374 
1375  if (m_QualsChangedCount) {
1376  m_DataIter->SetModified();
1377 
1378  string msg = "ISOJTA lookup, updated: ";
1379  for (const auto& it : m_TitlePairs) {
1380  msg += "'" + it.first + "' to '" + it.second + "'\n";
1381  }
1383  x_LogChangedQuals(fnc_log);
1384  }
1385 
1386  string msg;
1387  for (const auto& it : m_Hits) {
1388  if (it.second.empty()) {
1389  msg += "ISOJTA Lookup:\nNo ISOJTA title was found for '" + it.first + "'\n";
1390  }
1391  else {
1392  msg += "ISOJTA Lookup:\nMultiple titles were found for '" + it.first + "':\n";
1393  for (const auto& title_it : it.second) {
1394  msg += title_it + "\n";
1395  }
1396  }
1397  }
1398  if (!msg.empty()) {
1400  x_LogChangedQuals(fnc_log);
1401  }
1402 
1403 }
1404 
1406 {
1407  CTitle& title = journal.SetTitle();
1408 
1409  if (x_HasIsoJtaTitle(title)) {
1410  string old_title = x_GetIsoJtaTitle(title);
1411  vector<string> titles = x_FindIsoJtaTitle(old_title);
1412 
1413  if (titles.size() == 1) {
1414  // update existing ISOJTA only if lookup resulted in a new title
1415  if (old_title != titles[0]) {
1416  for (auto& it : title.Set()) {
1417  if (it->IsIso_jta()) {
1418  it->SetIso_jta(titles[0]);
1420  m_TitlePairs.emplace_back(old_title, titles[0]);
1421  }
1422  }
1423  }
1424  }
1425  else {
1426  if (find(titles.begin(), titles.end(), old_title) == titles.end()) {
1427  m_Hits.emplace(old_title, titles);
1428  }
1429  }
1430  }
1431  else {
1432  string old_title;
1433  for (auto& title_it : title.Set()) {
1434  if (title_it->IsJta() || title_it->IsName()) {
1435  old_title = title.GetTitle();
1436  vector<string> titles = x_FindIsoJtaTitle(old_title);
1437 
1438  if (titles.size() == 1) {
1439  title_it->SetIso_jta(titles[0]);
1441  m_TitlePairs.emplace_back(old_title, titles[0]);
1442  }
1443  else {
1444  m_Hits.emplace(old_title, titles);
1445  }
1446  }
1447  }
1448  }
1449 }
1450 
1452 {
1453  if (title.IsSet()) {
1454  for (const auto& title_it : title.Get()) {
1455  if (title_it->IsIso_jta()) {
1456  return true;
1457  }
1458  }
1459  }
1460  return false;
1461 }
1462 
1464 {
1465  if (title.IsSet()) {
1466  for (const auto& title_it : title.Get()) {
1467  if (title_it->IsIso_jta()) {
1468  return title_it->GetIso_jta();
1469  }
1470  }
1471  }
1472  return kEmptyStr;
1473 }
1474 
1475 vector<string> CMacroFunction_ISOJTALookup::x_FindIsoJtaTitle(const string& title)
1476 {
1477  vector<string> titles;
1478  if (m_DataIter->IsHugeDataMode()) {
1479  if (auto& isojta_updater = m_DataIter->ISOJTAUpdater(); isojta_updater) {
1480  isojta_updater->GetJournalAbbr(title, titles);
1481  }
1482  }
1483  else {
1484  CRef<CMacroBioData_PubdescIter> pubdesc_iter =
1486 
1487 
1488  auto& isojta_map = pubdesc_iter->SetISOJTALookupMap();
1489  if (auto it = isojta_map.find(title); it != isojta_map.end()) {
1490  titles = it->second;
1491  }
1492  else {
1493  CISOJTALookupWithCache::s_DoLookup(title, titles);
1494  isojta_map[title] = titles;
1495  }
1496  }
1497  return titles;
1498 }
1499 
1501 {
1502  return (m_Args.empty());
1503 }
1504 
1505 
1506 namespace {
1507 
1508  void GenerateFirstName(CAuthor& author)
1509  {
1510  if (author.IsSetName() && author.GetName().IsName()) {
1511  auto& std_name = author.SetName().SetName();
1512  if (std_name.IsSetInitials() && !std_name.IsSetFirst()) {
1513  std_name.SetFirst(std_name.GetInitials().substr(0, 1));
1514  }
1515  }
1516  }
1517 
1518  void FixMedLineList(CAuth_list& auth_list)
1519  {
1520  list<CRef<CAuthor>> standard_names;
1521 
1522  ITERATE(CAuth_list::TNames::TMl, it, auth_list.GetNames().GetMl()) {
1523  if (!NStr::IsBlank(*it)) {
1524  CRef<CAuthor> new_auth = CAuthor::ConvertMlToStandard(*it, true);
1525  if (new_auth) {
1526  GenerateFirstName(*new_auth);
1527  }
1528  standard_names.push_back(new_auth);
1529  }
1530  }
1531  auth_list.SetNames().Reset();
1532  auth_list.SetNames().SetStd().insert(auth_list.SetNames().SetStd().begin(), standard_names.begin(), standard_names.end());
1533  }
1534 
1535  void ConvertToStandardAuthors(CAuth_list& auth_list)
1536  {
1537  if (!auth_list.IsSetNames()) {
1538  return;
1539  }
1540 
1541  if (auth_list.GetNames().IsMl()) {
1542  FixMedLineList(auth_list);
1543  return;
1544  }
1545  else if (auth_list.GetNames().IsStd()) {
1546  NON_CONST_ITERATE(CAuth_list::TNames::TStd, it, auth_list.SetNames().SetStd()) {
1547  if ((*it)->GetName().IsMl()) {
1548  CRef<CAuthor> new_auth = CAuthor::ConvertMlToStandard(**it, true);
1549  if (new_auth) {
1550  GenerateFirstName(*new_auth);
1551  }
1552  (*it)->Assign(*new_auth);
1553  }
1554  }
1555  if (!auth_list.GetNames().GetStd().empty() && auth_list.GetNames().GetStd().front()->IsSetAffil()) {
1556  CRef<CAffil> affil(new CAffil);
1557  affil->Assign(auth_list.GetNames().GetStd().front()->GetAffil());
1558  auth_list.SetAffil(*affil);
1559  }
1560  }
1561  }
1562 
1563  void AdjustAuthors(CPubdesc& pubdesc)
1564  {
1565  for (auto& pub_it : pubdesc.SetPub().Set()) {
1566  if (pub_it->IsSetAuthors()) {
1567  auto& auth_list = pub_it->SetAuthors();
1568  if (auth_list.GetNames().IsStd()) {
1569  for (auto& it : auth_list.SetNames().SetStd()) {
1570  GenerateFirstName(*it);
1571  }
1572  if (!auth_list.GetNames().GetStd().empty() && auth_list.GetNames().GetStd().front()->IsSetAffil()) {
1573  CRef<CAffil> affil(new CAffil);
1574  affil->Assign(auth_list.GetNames().GetStd().front()->GetAffil());
1575  auth_list.SetAffil(*affil);
1576  }
1577  }
1578  }
1579  }
1580  }
1581 }
1582 
1583 ///////////////////////////////////////////////////////////////////////////////
1584 /// CMacroFunction_LookupPub
1585 /// PMIDLookup();
1586 ///
1589 {
1590  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
1591  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(obj.GetPointer());
1592  if (!const_pubdesc) {
1593  return;
1594  }
1595 
1596  CObjectInfo oi = m_DataIter->GetEditedObject();
1598  if (!pubdesc) {
1599  return;
1600  }
1601 
1602  if (m_DataIter->IsHugeDataMode()) {
1603  if (auto& remote_updater = m_DataIter->RemoteUpdater(); remote_updater) {
1604  CPubdesc orig_pubdesc;
1605  orig_pubdesc.Assign(*pubdesc);
1606 
1607  CSeqdesc desc;
1608  desc.SetPub(*pubdesc);
1609  remote_updater->UpdatePubReferences(desc);
1610  AdjustAuthors(*pubdesc);
1611 
1612  if (!pubdesc->Equals(orig_pubdesc)) {
1614  }
1615  }
1616  }
1617  else {
1618  CRef<CMacroBioData_PubdescIter> pubdesc_iter =
1620 
1621  // look for a PMID pub
1622  if (pubdesc->IsSetPub() && pubdesc->GetPub().IsSet()) {
1623  for (auto&& it : pubdesc->SetPub().Set()) {
1624  if (it->IsPmid()) {
1625  TEntrezId pmid = it->GetPmid().Get();
1626  CRef<CPub> looked_up_pub(nullptr);
1627  CMacroBioData_PubdescIter::TPmidLookupMap& map = pubdesc_iter->SetPmidLookupMap();
1628  auto it = map.find(pmid);
1629  if (it != map.end()) {
1630  looked_up_pub = it->second;
1631  }
1632  else {
1633  looked_up_pub = s_GetArticleFromEntrezById(pmid);
1634  if (looked_up_pub) {
1635  map.emplace(pmid, looked_up_pub);
1636  }
1637  }
1638 
1639  if (looked_up_pub) {
1640  pubdesc->Reset();
1641  CRef<CPub> pmid_pub(new CPub());
1642  pmid_pub->SetPmid().Set(pmid);
1643  pubdesc->SetPub().Set().push_back(pmid_pub);
1644  pubdesc->SetPub().Set().push_back(looked_up_pub);
1646  break;
1647  }
1648  }
1649  }
1650  }
1651  }
1652 
1653  if (m_QualsChangedCount) {
1654  m_DataIter->SetModified();
1655  TChangedQuals report;
1656  report["pmid lookup"] = m_QualsChangedCount;
1657  CRef<IFunctionLog> fnc_log(new CGeneralFuncLog(report));
1658  x_LogChangedQuals(fnc_log);
1659  }
1660 }
1661 
1663 {
1664  return (m_Args.empty());
1665 }
1666 
1667 
1669 {
1670  CRef<CPub> pub(nullptr);
1671 
1672  if (asn_format) {
1673  // prepare eFetch request
1674  CGuiEutilsClient ecli;
1675  ecli.SetMaxReturn(1);
1676 
1677  vector<TEntrezId> uids;
1678  uids.push_back(id);
1679 
1680  CRef<CPubmed_entry> pubmed_entry(new CPubmed_entry());
1681  CNcbiStrstream asnPubMedEntry;
1682  try {
1683  ecli.Fetch("pubmed", uids, asnPubMedEntry, "asn.1");
1684  asnPubMedEntry >> MSerial_AsnText >> *pubmed_entry;
1685  }
1686  catch (const CException& e) {
1687  LOG_POST(Error << "CMacroFunction_LookupPub::s_GetArticleFromEntrezById(): error fetching ID " << id << ": " << e.GetMsg());
1688  return pub;
1689  }
1690  if (pubmed_entry->IsSetMedent() && pubmed_entry->GetMedent().IsSetCit()) {
1691  pub.Reset(new CPub());
1692  pub->SetArticle().Assign(pubmed_entry->GetMedent().GetCit());
1693  if (pub->GetArticle().IsSetAuthors()) {
1694  ConvertToStandardAuthors(pub->SetArticle().SetAuthors());
1695  }
1696  }
1697  }
1698  else {
1699  // return pub in XML format
1700  edit::CEUtilsUpdater updater;
1702  pub = updater.GetPub(id, &error);
1703  if (pub) {
1704  if (pub->IsSetAuthors()) {
1705  ConvertToStandardAuthors(pub->SetAuthors());
1706  }
1707  }
1708  else {
1709  CNcbiOstrstream oss;
1710  oss << error;
1711  const string err_msg = oss.str();
1712  LOG_POST(Error << "CMacroFunction_LookupPub::s_GetArticleFromEntrezById(): error fetching ID " << id << ": " << err_msg);
1713  return pub;
1714  }
1715  }
1716 
1717  return pub;
1718 }
1719 
1720 ///////////////////////////////////////////////////////////////////////////////
1721 /// class CMacroFunction_DOILookup
1722 /// DOILookup(doi_number);
1723 ///
1724 DEFINE_MACRO_FUNCNAME(CMacroFunction_DOILookup, "DOILookup")
1725 void CMacroFunction_DOILookup::TheFunction()
1726 {
1727  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
1728  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(obj.GetPointer());
1729  if (!const_pubdesc) {
1730  return;
1731  }
1732 
1733  CObjectInfo oi = m_DataIter->GetEditedObject();
1735  if (!pubdesc) {
1736  return;
1737  }
1738 
1739  const string& new_doi = m_Args[0]->GetString();
1740  if (new_doi.empty())
1741  return;
1742 
1743  // update only unpublished cit-gen references
1744  bool modify = false;
1745  for (const auto& it : pubdesc->GetPub().Get()) {
1746  if (it->IsGen()) {
1747  const CCit_gen& genref = it->GetGen();
1748  if (genref.IsSetCit() && NStr::EqualNocase(genref.GetCit(), "unpublished")) {
1749  modify = true;
1750  break;
1751  }
1752  }
1753  }
1754  if (!modify)
1755  return;
1756 
1757  if (m_DataIter->IsHugeDataMode()) {
1758  if (auto& doi_updater = m_DataIter->DOIUpdater(); doi_updater) {
1759  pair<CRef<CPubdesc>, string> new_pubdesc_str = doi_updater->GetPub(new_doi);
1760  if (new_pubdesc_str.first) {
1761  pubdesc->Reset();
1762  pubdesc->Assign(*new_pubdesc_str.first);
1763  m_QualsChangedCount++;
1764  }
1765  else {
1767  log << "Problem resolving DOI '" << new_doi << ": " << new_pubdesc_str.second;
1768  x_LogError(log);
1769  }
1770  }
1771  }
1772  else {
1773  CRef<CMacroBioData_PubdescIter> pubdesc_iter =
1774  Ref(dynamic_cast<CMacroBioData_PubdescIter*>(m_DataIter.GetPointer()));
1775 
1776  CRef<CPubdesc> looked_up_pubdesc(nullptr);
1777  CMacroBioData_PubdescIter::TDOILookupMap& map = pubdesc_iter->SetDOILookupMap();
1778  auto it = map.find(new_doi);
1779  if (it != map.end()) {
1780  looked_up_pubdesc = it->second;
1781  }
1782  else {
1783  pair<CRef<CPubdesc>, string> new_pubdesc_str = CDoiLookup::GetPubFromCrossRef(new_doi);
1784  looked_up_pubdesc = new_pubdesc_str.first;
1785  if (looked_up_pubdesc) {
1786  map.emplace(new_doi, looked_up_pubdesc);
1787  }
1788  else {
1790  log << "Problem resolving DOI '" << new_doi << ": " << new_pubdesc_str.second;
1791  x_LogError(log);
1792  }
1793  }
1794 
1795  if (looked_up_pubdesc) {
1796  pubdesc->Reset();
1797  pubdesc->Assign(*looked_up_pubdesc);
1798  _ASSERT(pubdesc->Equals(*looked_up_pubdesc));
1799  m_QualsChangedCount++;
1800  }
1801  }
1802 
1803  if (m_QualsChangedCount) {
1804  m_DataIter->SetModified();
1805  TChangedQuals report;
1806  report["doi lookup"] = m_QualsChangedCount;
1807  CRef<IFunctionLog> fnc_log(new CGeneralFuncLog(report));
1808  x_LogChangedQuals(fnc_log);
1809  }
1810 }
1811 
1812 bool CMacroFunction_DOILookup::x_ValidArguments() const
1813 {
1814  return (m_Args.size() == 1) && (m_Args[0]->IsString());
1815 }
1816 
1817 
1818 ///////////////////////////////////////////////////////////////////////////////
1819 /// class CMacroFunction_GlobalDOILookup
1820 /// GlobalDOILookup();
1821 /// Function looks up DOI names stored in Cit-gen.cit members (GB-9328)
1822 ///
1823 DEFINE_MACRO_FUNCNAME(CMacroFunction_GlobalDOILookup, "GlobalDOILookup")
1824 void CMacroFunction_GlobalDOILookup::TheFunction()
1825 {
1826  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
1827  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(obj.GetPointer());
1828  if (!const_pubdesc) {
1829  return;
1830  }
1831 
1832  CObjectInfo oi = m_DataIter->GetEditedObject();
1834  if (!pubdesc) {
1835  return;
1836  }
1837 
1838  // use DOI name from cit-gen.cit member
1839  string doi_name;
1840  for (const auto& it : pubdesc->GetPub().Get()) {
1841  if (it->IsGen() && it->GetGen().IsSetCit()) {
1842  const string& citation = it->GetGen().GetCit();
1843 
1845  doi_name = citation;
1846  if (NStr::StartsWith(doi_name, "doi:", NStr::eNocase)) {
1847  NStr::ReplaceInPlace(doi_name, "doi:", "");
1848  NStr::ReplaceInPlace(doi_name, "DOI:", "");
1849  NStr::TruncateSpacesInPlace(doi_name);
1850  }
1851  }
1852  }
1853  }
1854 
1855  if (doi_name.empty())
1856  return;
1857 
1858  if (m_DataIter->IsHugeDataMode()) {
1859  if (auto& doi_updater = m_DataIter->DOIUpdater(); doi_updater) {
1860  pair<CRef<CPubdesc>, string> new_pubdesc_str = doi_updater->GetPub(doi_name);
1861  if (new_pubdesc_str.first) {
1862  pubdesc->Reset();
1863  pubdesc->Assign(*new_pubdesc_str.first);
1864  m_QualsChangedCount++;
1865  }
1866  else {
1868  log << "Problem resolving DOI '" << doi_name << ": " << new_pubdesc_str.second;
1869  x_LogError(log);
1870  }
1871  }
1872  }
1873  else {
1874  CRef<CMacroBioData_PubdescIter> pubdesc_iter =
1875  Ref(dynamic_cast<CMacroBioData_PubdescIter*>(m_DataIter.GetPointer()));
1876 
1877  CRef<CPubdesc> looked_up_pubdesc(nullptr);
1878  CMacroBioData_PubdescIter::TDOILookupMap& map = pubdesc_iter->SetDOILookupMap();
1879 
1880  auto it = map.find(doi_name);
1881  if (it != map.end()) {
1882  looked_up_pubdesc = it->second;
1883  }
1884  else {
1885  pair<CRef<CPubdesc>, string> new_pubdesc_str = CDoiLookup::GetPubFromCrossRef(doi_name);
1886  looked_up_pubdesc = new_pubdesc_str.first;
1887  if (looked_up_pubdesc) {
1888  map.emplace(doi_name, looked_up_pubdesc);
1889  }
1890  else {
1892  log << "Problem resolving DOI '" << doi_name << "': " << new_pubdesc_str.second;
1893  x_LogError(log);
1894  }
1895  }
1896 
1897  if (looked_up_pubdesc) {
1898  pubdesc->Reset();
1899  pubdesc->Assign(*looked_up_pubdesc);
1900  _ASSERT(pubdesc->Equals(*looked_up_pubdesc));
1901  m_QualsChangedCount++;
1902  }
1903  }
1904 
1905  if (m_QualsChangedCount) {
1906  m_DataIter->SetModified();
1907  TChangedQuals report;
1908  report["doi lookup"] = m_QualsChangedCount;
1909  CRef<IFunctionLog> fnc_log(new CGeneralFuncLog(report));
1910  x_LogChangedQuals(fnc_log);
1911  }
1912 }
1913 
1914 bool CMacroFunction_GlobalDOILookup::x_ValidArguments() const
1915 {
1916  return (m_Args.empty());
1917 }
1918 
1919 ///////////////////////////////////////////////////////////////////////////////
1920 /// class CMacroFunction_SetPubTitle
1921 /// SetPubTitle(title_object, newValue, existingtext_option, delimiter, remove_blank)
1922 /// The last two parameters are optional
1923 ///
1925 void CMacroFunction_SetPubTitle::TheFunction()
1926 {
1927  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
1928  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
1929  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
1930  if (!const_pubdesc && !const_block)
1931  return;
1932 
1933  CObjectInfo oi = m_DataIter->GetEditedObject();
1934  CMQueryNodeValue::TObs res_oi;
1935  x_GetObjectsFromRef(res_oi, 0);
1936 
1937  size_t index = 1;
1938  const string& newValue = m_Args[index]->GetString();
1939  const string& action_type = m_Args[++index]->GetString();
1940  string delimiter;
1941  bool remove_field = false;
1942  x_GetOptionalArgs(delimiter, remove_field, index);
1944 
1945  if (!newValue.empty()) {
1946  if (res_oi.empty()) {
1947  //create a new publication title
1948  if (const_pubdesc) {
1950  x_SetTitleInPubdesc(*pubdesc, newValue);
1951  }
1952  else if (const_block) {
1954  x_SetTitleInSubmitBlock(*submit_block, newValue);
1955  }
1956  }
1957  else {
1959  CObjectInfo obj = it->field;
1960  if (obj.GetTypeFamily() == eTypeFamilyPrimitive) {
1962  string orig_value = obj.GetPrimitiveValueString();
1963  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
1964  SetQualStringValue(obj, orig_value);
1965  }
1966  }
1967  }
1968  }
1969  }
1970 
1971  if (m_QualsChangedCount) {
1972  m_DataIter->SetModified();
1974  log << m_DataIter->GetBestDescr() << ": set " << m_QualsChangedCount << " publication title";
1975  x_LogFunction(log);
1976  }
1977  }
1978  else if (remove_field) {
1979  m_QualsChangedCount = CMacroFunction_RemoveQual::s_RemoveFields(m_DataIter, res_oi);
1980  if (m_QualsChangedCount) {
1981  m_DataIter->SetModified();
1983  log << m_DataIter->GetBestDescr() << ": removed " << m_QualsChangedCount << " publication title";
1984  x_LogFunction(log);
1985  }
1986  }
1987 }
1988 
1990 {
1991  auto arg_nr = m_Args.size();
1992  if (arg_nr > 5 || arg_nr < 3) {
1993  return false;
1994  }
1995  size_t index = 0;
1996  if (!m_Args[index]->IsRef()) {
1997  return false;
1998  }
1999  NMacroUtil::GetPrimitiveFromRef(m_Args[++index].GetNCObject());
2000  bool second_ok = m_Args[index]->IsString() || m_Args[index]->IsInt() || m_Args[index]->IsDouble();
2001  if (!second_ok) return false;
2002 
2003  if (!m_Args[++index]->IsString()) return false;
2004  if (arg_nr > 3 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
2005  if (arg_nr > 4 && !m_Args[++index]->IsBool()) return false;
2006  return true;
2007 }
2008 
2010 {
2011  CRef<CTitle::C_E> title(new CTitle::C_E());
2012  title->SetName(value);
2013  for (auto& it : pubdesc.SetPub().Set()) {
2014  switch (it->Which())
2015  {
2016  case CPub::e_Gen:
2017  it->SetGen().SetTitle(value);
2019  break;
2020  case CPub::e_Sub:
2021  it->SetSub().SetDescr(value);
2023  break;
2024  case CPub::e_Article:
2025  it->SetArticle().SetTitle().Set().push_back(title);
2027  break;
2028  case CPub::e_Book:
2029  it->SetBook().SetTitle().Set().push_back(title);
2031  break;
2032  case CPub::e_Proc:
2033  it->SetProc().SetBook().SetTitle().Set().push_back(title);
2035  break;
2036  case CPub::e_Patent:
2037  it->SetPatent().SetTitle(value);
2039  break;
2040  case CPub::e_Man:
2041  it->SetMan().SetCit().SetTitle().Set().push_back(title);
2043  break;
2044  case CPub::e_Medline:
2045  case CPub::e_Journal:
2046  case CPub::e_Pat_id:
2047  case CPub::e_Equiv:
2048  case CPub::e_Pmid:
2049  default:
2050  break;
2051  }
2052  }
2053 }
2054 
2056 {
2057  if (submit_block.IsSetCit()) {
2058  submit_block.SetCit().SetDescr(value);
2060  }
2061 }
2062 
2063 ///////////////////////////////////////////////////////////////////////////////
2064 /// CMacroFunction_SetPubAffil
2065 /// SetPubAffil("affil", new_value, existing_text, delimiter, remove_blank)
2066 /// SetPubAffil("city", new_value, existing_text, delimiter, remove_blank)
2067 /// The last two parameters are optional
2068 ///
2070 void CMacroFunction_SetPubAffil::TheFunction()
2071 {
2072  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2073  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2074  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2075  if (!const_pubdesc && !const_block)
2076  return;
2077 
2078  size_t index = 0;
2079  const string& field = m_Args[index]->GetString();
2080  const string& newValue = NMacroUtil::GetStringValue(m_Args[++index]);
2081  const string& action_type = m_Args[++index]->GetString();
2082  string delimiter;
2083  bool remove_field = false;
2084  x_GetOptionalArgs(delimiter, remove_field, index);
2086 
2088  if (!newValue.empty()) {
2089  CObjectInfo oi = m_DataIter->GetEditedObject();
2090  if (const_pubdesc) {
2092  for (auto& it : pubdesc->SetPub().Set()) {
2093  if (it->IsSetAuthors()) {
2094  x_SetAffilField(it->SetAuthors(), field, newValue, existing_text);
2095  break;
2096  }
2097  }
2098  }
2099  else if (const_block) {
2101  if (submit_block->IsSetCit() && submit_block->SetCit().IsSetAuthors()) {
2102  x_SetAffilField(submit_block->SetCit().SetAuthors(), field, newValue, existing_text);
2103  }
2104  }
2105 
2106  if (m_QualsChangedCount) {
2107  log << m_DataIter->GetBestDescr() << ": set ";
2108  }
2109  }
2110  else if (remove_field) {
2111  CObjectInfo oi = m_DataIter->GetEditedObject();
2112  if (const_pubdesc) {
2114  for (auto& it : pubdesc->SetPub().Set()) {
2115  if (it->IsSetAuthors()) {
2116  x_RemoveAffilField(it->SetAuthors(), field);
2117  break;
2118  }
2119  }
2120  }
2121  if (m_QualsChangedCount) {
2122  log << m_DataIter->GetBestDescr() << ": removed ";
2123  }
2124  }
2125 
2126  if (m_QualsChangedCount) {
2127  m_DataIter->SetModified();
2128  log << m_QualsChangedCount << " publication ";
2129  if (field == "affil") {
2130  log << "institution";
2131  }
2132  else if (field == "div") {
2133  log << "department";
2134  }
2135  else if (field == "sub") {
2136  log << "state";
2137  }
2138  else {
2139  log << field;
2140  }
2141  x_LogFunction(log);
2142  }
2143 }
2144 
2146 {
2147  auto arg_nr = m_Args.size();
2148  if (arg_nr < 3 || arg_nr > 5) {
2149  return false;
2150  }
2151 
2152  size_t index = 0;
2153  if (!m_Args[index]->IsString()) return false;
2154  NMacroUtil::GetPrimitiveFromRef(m_Args[++index].GetNCObject());
2155  if (!m_Args[index]->IsString() && !m_Args[index]->IsInt()) {
2156  return false;
2157  }
2158  if (!m_Args[++index]->IsString()) return false;
2159  if (arg_nr > 3 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
2160  if (arg_nr > 4 && !m_Args[++index]->IsBool()) return false;
2161  return true;
2162 }
2163 
2164 void CMacroFunction_SetPubAffil::x_SetAffilField(CAuth_list& auth_list, const string& field, const string& newValue, edit::EExistingText existing_text)
2165 {
2166  CObjectInfo oi(&auth_list, auth_list.GetThisTypeInfo());
2167  string field_name = "affil.std." + field;
2168  CMQueryNodeValue::TObs res_oi;
2169  if (!SetFieldsByName(&res_oi, oi, field_name)) {
2170  return;
2171  }
2172  _ASSERT(!res_oi.empty());
2173  string orig_value = res_oi.front().field.GetPrimitiveValueString();
2174  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
2175  SetQualStringValue(res_oi.front().field, orig_value);
2176  }
2177 }
2178 
2179 void CMacroFunction_SetPubAffil::x_RemoveAffilField(CAuth_list& auth_list, const string& field)
2180 {
2181  CObjectInfo oi(&auth_list, auth_list.GetThisTypeInfo());
2182  string field_name = "affil.std." + field;
2183  CMQueryNodeValue::TObs res_oi;
2184  if (!GetFieldsByName(&res_oi, oi, field_name)) {
2185  return;
2186  }
2188 }
2189 
2190 ///////////////////////////////////////////////////////////////////////////////
2191 /// class CMacroFunction_SetPubAuthor
2192 /// SetPubAuthorName(author_object, field_name, newValue, existingtext_option, delimiter, remove_blank)
2193 ///
2195 void CMacroFunction_SetPubAuthor::TheFunction()
2196 {
2197  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2198  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2199  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2200  if (!const_pubdesc && !const_block)
2201  return;
2202 
2203  CObjectInfo oi = m_DataIter->GetEditedObject();
2204  CMQueryNodeValue::TObs res_oi;
2205  size_t index = 0;
2206  if (m_Args[index]->AreObjects()) {
2207  res_oi = m_Args[index]->GetObjects();
2208  }
2209  else if (m_Args[index]->IsRef()) {
2210  x_GetObjectsFromRef(res_oi, index);
2211  }
2212 
2213  const string& field = m_Args[++index]->GetString();
2214  const string& newValue = m_Args[++index]->GetString();
2215  const string& action_type = m_Args[++index]->GetString();
2216  string delimiter;
2217  bool remove_field = false;
2218  x_GetOptionalArgs(delimiter, remove_field, index);
2220 
2221 
2222  if (!newValue.empty()) {
2223  if (existing_text == edit::eExistingText_add_qual) {
2224  //create a new publication author and populate the specified field
2225  if (const_pubdesc) {
2227  x_SetAuthorInPubdesc(*pubdesc, field, *m_Args[2], existing_text);
2228  }
2229  else if (const_block) {
2231  if (submit_block->IsSetCit()) {
2232  x_SetNewAuthor(submit_block->SetCit().SetAuthors(), field, *m_Args[2]);
2233  }
2234  }
2235  }
2236  else {
2237  for (auto&& it : res_oi) {
2238  CObjectInfo obj = it.field;
2239  if (obj.GetTypeFamily() == eTypeFamilyPrimitive) {
2241  string orig_value = obj.GetPrimitiveValueString();
2242  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
2243  SetQualStringValue(obj, orig_value);
2244  }
2245  }
2246  }
2247  else if (obj.GetTypeFamily() == eTypeFamilyClass) {
2248  if (NStr::EqualNocase(obj.GetName(), "Name-std")) {
2249  if (field == "consortium") {
2250  CObjectInfo parent_oi = it.parent;
2252  if (person_id) {
2253  person_id->SetConsortium() = newValue;
2254  m_QualsChangedCount++;
2255  }
2256  }
2257  else if (field == "first") {
2259  if (std_name && NMacroUtil::ApplyFirstName(*std_name, newValue, existing_text)) {
2260  m_QualsChangedCount++;
2261  }
2262  }
2263  else if (ResolveAndSetSimpleTypeValue(obj, field, *m_Args[2], existing_text)) {
2264  m_QualsChangedCount++;
2265  }
2266  }
2267  }
2268  }
2269  }
2270 
2271  if (m_QualsChangedCount) {
2272  m_DataIter->SetModified();
2274  log << m_DataIter->GetBestDescr() << ": set " << m_QualsChangedCount << " publication author field";
2275  x_LogFunction(log);
2276  }
2277  }
2278  else if (remove_field) {
2279  for (auto&& it : res_oi) {
2280  CObjectInfo obj = it.field;
2281  if (obj.GetTypeFamily() == eTypeFamilyPrimitive) {
2282  if (RemoveFieldByName(it)) {
2283  m_QualsChangedCount++;
2284  }
2285  }
2286  else if (obj.GetTypeFamily() == eTypeFamilyClass) {
2287  if (NStr::EqualNocase(obj.GetName(), "Name-std")) {
2288  CMQueryNodeValue::TObs sub_objs;
2289  GetFieldsByName(&sub_objs, obj, field);
2290  m_QualsChangedCount += CMacroFunction_RemoveQual::s_RemoveFields(m_DataIter, sub_objs);
2291  }
2292  }
2293  }
2294  if (const_pubdesc) {
2296  for (auto& it : pubdesc->SetPub().Set()) {
2297  CAuth_list& auth_list = it->SetAuthors();
2298  if (auth_list.IsSetNames() && auth_list.GetNames().IsStd()) {
2299  auto& authors = auth_list.SetNames().SetStd();
2300  CAuth_list_Base::TNames::TStd::iterator auth_it = authors.begin();
2301  while (auth_it != authors.end()) {
2302  if ((*auth_it)->IsSetName() &&
2303  (*auth_it)->GetName().IsConsortium() &&
2304  (*auth_it)->GetName().GetConsortium().empty()) {
2305  auth_it = authors.erase(auth_it);
2306  }
2307  else {
2308  ++auth_it;
2309  }
2310  }
2311  }
2312  }
2313  }
2314  if (m_QualsChangedCount) {
2315  m_DataIter->SetModified();
2317  log << m_DataIter->GetBestDescr() << ": removed " << m_QualsChangedCount << " publication author field";
2318  x_LogFunction(log);
2319  }
2320 
2321  }
2322 }
2323 
2325 {
2326  auto arg_nr = m_Args.size();
2327  if (arg_nr > 6 || arg_nr < 4) {
2328  return false;
2329  }
2330 
2331  size_t index = 0;
2332  if (!m_Args[index]->IsRef() && !m_Args[index]->AreObjects()) {
2333  return false;
2334  }
2335  NMacroUtil::GetPrimitiveFromRef(m_Args[2].GetNCObject());
2336  index = 4;
2337  for (size_t i = 1; i < index; ++i) {
2338  if (!m_Args[i]->IsString()) {
2339  return false;
2340  }
2341  }
2342  if (arg_nr > 4 && (!m_Args[index]->IsString() && !m_Args[index]->IsBool())) return false;
2343  if (arg_nr > 5 && !m_Args[++index]->IsBool()) return false;
2344  return true;
2345 }
2346 
2348 {
2349  for (auto& it : pubdesc.SetPub().Set()) {
2350  CAuth_list* auth_list = nullptr;
2351  if (it->IsSetAuthors()) {
2352  auth_list = &(it->SetAuthors());
2353  }
2354  else {
2355  try {
2356  auth_list = &(it->SetAuthors());
2357  }
2358  catch (const CException&) { /* can not set the authors */ }
2359  }
2360  if (auth_list) {
2361  x_SetNewAuthor(*auth_list, field, value);
2362  }
2363  }
2364 }
2365 
2367 {
2368  CRef<CAuthor> new_author(new CAuthor);
2369  CObjectInfo oi(new_author, new_author->GetThisTypeInfo());
2370  string field_name;
2371  if (field == "consortium") {
2372  field_name = "name." + field;
2373  }
2374  else {
2375  field_name = "name.name." + field;
2376  }
2378  auth_list.SetNames().SetStd().push_back(new_author);
2380  }
2381 }
2382 
2383 ///////////////////////////////////////////////////////////////////////////////
2384 // class CMacroFunction_SetPubAuthorMI
2385 /// SetPubAuthorMI(author_object, newValue, existingtext_option, delimiter, remove_blank)
2386 ///
2387 DEFINE_MACRO_FUNCNAME(CMacroFunction_SetPubAuthorMI, "SetPubAuthorMI")
2388 void CMacroFunction_SetPubAuthorMI::TheFunction()
2389 {
2390  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2391  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2392  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2393  if (!const_pubdesc && !const_block)
2394  return;
2395 
2396  CObjectInfo oi = m_DataIter->GetEditedObject();
2397  CMQueryNodeValue::TObs res_oi;
2398  if (m_Args[0]->AreObjects()) {
2399  res_oi = m_Args[0]->GetObjects();
2400  }
2401  else if (m_Args[0]->IsRef()) {
2402  x_GetObjectsFromRef(res_oi, 0);
2403  }
2404 
2405  size_t index = 1;
2406  const string& newValue = m_Args[index]->GetString();
2407  const string& action_type = m_Args[++index]->GetString();
2408  string delimiter;
2409  bool remove_field = false;
2410  x_GetOptionalArgs(delimiter, remove_field, index);
2412 
2413  if (existing_text == edit::eExistingText_add_qual) {
2414  return;
2415  }
2416 
2418  log << m_DataIter->GetBestDescr();
2419 
2420  if (!newValue.empty()) {
2421  for (auto&& it : res_oi) {
2422  CObjectInfo obj = it.field;
2423  if (obj.GetTypeFamily() == eTypeFamilyPrimitive) {
2425  string orig_value = obj.GetPrimitiveValueString();
2426  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
2427  SetQualStringValue(obj, orig_value);
2428  }
2429  }
2430  }
2431  else if (obj.GetTypeFamily() == eTypeFamilyClass && NStr::EqualNocase(obj.GetName(), "Name-std")) {
2433  if (std_name && NMacroUtil::ApplyMiddleInitial(*std_name, newValue, existing_text)) {
2434  m_QualsChangedCount++;
2435  }
2436  }
2437  }
2438 
2439  if (m_QualsChangedCount) {
2440  log << ": set ";
2441  }
2442  }
2443  else if (remove_field) {
2444  for (auto&& it : res_oi) {
2445  CObjectInfo obj = it.field;
2446  if (obj.GetTypeFamily() == eTypeFamilyClass && NStr::EqualNocase(obj.GetName(), "Name-std")) {
2448  if (std_name && NMacroUtil::RemoveMiddleInitial(*std_name)) {
2449  m_QualsChangedCount++;
2450  }
2451  }
2452  }
2453 
2454  if (m_QualsChangedCount) {
2455  log << ": removed ";
2456  }
2457  }
2458  if (m_QualsChangedCount) {
2459  m_DataIter->SetModified();
2460  log << m_QualsChangedCount << " publication author middle initial";
2461  x_LogFunction(log);
2462  }
2463 }
2464 
2465 bool CMacroFunction_SetPubAuthorMI::x_ValidArguments() const
2466 {
2467  auto arg_nr = m_Args.size();
2468  if (arg_nr > 5 || arg_nr < 3) {
2469  return false;
2470  }
2471  size_t index = 0;
2472  if (!m_Args[index]->IsRef() && !m_Args[index]->AreObjects()) {
2473  return false;
2474  }
2475  NMacroUtil::GetPrimitiveFromRef(m_Args[++index].GetNCObject());
2476  if (!m_Args[index]->IsString() || !m_Args[++index]->IsString())
2477  return false;
2478 
2479  if (arg_nr > 3 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
2480  if (arg_nr > 4 && !m_Args[++index]->IsBool()) return false;
2481  return true;
2482 }
2483 
2484 
2485 ///////////////////////////////////////////////////////////////////////////////
2486 /// class CMacroFunction_AddPubAuthors
2487 /// AddAuthor(last_name, first_name, middle initial, suffix, existingtext_option)
2488 ///
2490 void CMacroFunction_AddPubAuthor::TheFunction()
2491 {
2492  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2493  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2494  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2495  if (!const_pubdesc && !const_block)
2496  return;
2497 
2498  // do not add author if the last name is empty
2499  if (m_Args[0]->GetString().empty()) {
2500  return;
2501  }
2502  edit::EExistingText existing_text = NMacroUtil::ActionTypeToExistingTextOption(m_Args[4]->GetString(), kEmptyStr);
2503 
2504  CObjectInfo oi = m_DataIter->GetEditedObject();
2505  if (const_pubdesc) {
2507  x_AddAuthorInPubdesc(*pubdesc, existing_text);
2508  }
2509  else if (const_block) {
2511  if (submit_block->IsSetCit()) {
2512  x_AddAuthor(submit_block->SetCit().SetAuthors(), existing_text);
2513  }
2514  }
2515 
2516  if (m_QualsChangedCount) {
2517  m_DataIter->SetModified();
2519  log << m_DataIter->GetBestDescr() << ": added " << m_QualsChangedCount << " publication author";
2520  x_LogFunction(log);
2521  }
2522 }
2523 
2525 {
2526  if (m_Args.empty() || m_Args.size() > 5) {
2527  return false;
2528  }
2529 
2530  for (auto& it : m_Args) {
2531  if (!it->IsString()) {
2532  return false;
2533  }
2534  }
2535  return true;
2536 }
2537 
2539 {
2540  for (auto& it : pubdesc.SetPub().Set()) {
2541  CAuth_list* auth_list = nullptr;
2542  if (it->IsSetAuthors()) {
2543  auth_list = &(it->SetAuthors());
2544  }
2545  else {
2546  try {
2547  auth_list = &(it->SetAuthors());
2548  }
2549  catch (const CException&) { /* can not set the authors */ }
2550  }
2551  if (auth_list)
2552  x_AddAuthor(*auth_list, existing_text);
2553  }
2554 }
2555 
2557 {
2558  CRef<CAuthor> author(new CAuthor);
2559  CName_std& std_name = author->SetName().SetName();
2560  std_name.SetLast(m_Args[0]->GetString());
2561  if (!m_Args[1]->GetString().empty()) {
2562  std_name.SetFirst(m_Args[1]->GetString());
2563  }
2564 
2565  const string middle_init = m_Args[2]->GetString();
2566  string initials = (std_name.IsSetFirst()) ? CMacroFunction_AuthorFix::s_GetFirstNameInitials(std_name.GetFirst()) : kEmptyStr;
2567  if (!middle_init.empty()) {
2568  initials.append(middle_init);
2569  }
2570  // don't add another period if one is already there
2571  if (!NStr::EndsWith(initials, ".")) {
2572  initials.append(".");
2573  }
2574  if (!initials.empty()) {
2575  std_name.SetInitials(initials);
2576  }
2577  if (!m_Args[3]->GetString().empty()) {
2578  std_name.SetSuffix(m_Args[3]->GetString());
2579  }
2580 
2581  if (existing_text == edit::eExistingText_replace_old) {
2582  auth_list.ResetNames();
2583  auth_list.SetNames().SetStd().push_back(author);
2585  }
2586  else if (existing_text == edit::eExistingText_append_none) {
2587  auth_list.SetNames().SetStd().push_back(author);
2589  }
2590  else if (existing_text == edit::eExistingText_prefix_none) {
2591  auto& names = auth_list.SetNames().SetStd();
2592  names.insert(names.begin(), author);
2594  }
2595 }
2596 
2597 
2598 ///////////////////////////////////////////////////////////////////////////////
2599 /// class CMacroFunction_AddAuthorList
2600 /// AddAuthorList(author_list, remove_blank)
2601 /// The only option for it is to overwrite existing values
2602 /// The last parameter is optional
2603 ///
2605 void CMacroFunction_AddAuthorList::TheFunction()
2606 {
2607  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2608  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2609  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2610  if (!const_pubdesc && !const_block)
2611  return;
2612 
2613  size_t index = 0;
2614  const string& newValue = m_Args[index]->GetString();
2615  bool remove_field = (++index < m_Args.size()) ? m_Args[index]->GetBool() : false;
2616 
2617  CObjectInfo oi = m_DataIter->GetEditedObject();
2619  log << m_DataIter->GetBestDescr();
2620 
2621  if (!newValue.empty()) {
2622  if (const_pubdesc) {
2624  x_AddAuthorListInPubdesc(*pubdesc);
2625  }
2626  else if (const_block) {
2628  if (submit_block->IsSetCit()) {
2629  m_QualsChangedCount = NMacroUtil::ApplyAuthorNames(submit_block->SetCit().SetAuthors(), m_Args[0]->GetString());
2630  }
2631  }
2632 
2633  if (m_QualsChangedCount) {
2634  log << ": added ";
2635  }
2636  }
2637  else if (remove_field) {
2638  if (const_pubdesc) {
2640  for (auto& it : pubdesc->SetPub().Set()) {
2641  if (it->IsSetAuthors()) {
2642  CAuth_list& auth_list = it->SetAuthors();
2643  m_QualsChangedCount += (Int4)auth_list.GetNameCount();
2644  auth_list.ResetNames();
2645  auth_list.SetNames().SetStr().push_back("?");
2646  }
2647  }
2648  }
2649  if (m_QualsChangedCount) {
2650  log << ": removed ";
2651  }
2652  }
2653 
2654  if (m_QualsChangedCount) {
2655  m_DataIter->SetModified();
2656  log << m_QualsChangedCount << " author names";
2657  x_LogFunction(log);
2658  }
2659 }
2660 
2662 {
2663  if (m_Args.empty() || m_Args.size() > 2)
2664  return false;
2665 
2666  size_t index = 0;
2667  NMacroUtil::GetPrimitiveFromRef(m_Args[index].GetNCObject());
2668  if (!m_Args[index]->IsString())
2669  return false;
2670  if (++index < m_Args.size() && !m_Args[index]->IsBool())
2671  return false;
2672 
2673  return true;
2674 }
2675 
2677 {
2678  for (auto& it : pubdesc.SetPub().Set()) {
2679  CAuth_list* auth_list = nullptr;
2680  if (it->IsSetAuthors()) {
2681  auth_list = &(it->SetAuthors());
2682  }
2683  else {
2684  try {
2685  auth_list = &(it->SetAuthors());
2686  }
2687  catch (const CException&) { /* can not set the authors */ }
2688  }
2689  if (auth_list) {
2690  // Note that Suffix is only be parsed correctly when four names are specified
2691  m_QualsChangedCount = NMacroUtil::ApplyAuthorNames(*auth_list, m_Args[0]->GetString());
2692  }
2693  }
2694 }
2695 
2696 ///////////////////////////////////////////////////////////////////////////////
2697 /// class CMacroFunction_SetPubJournal
2698 /// SetPubJournal(newValue, existingtext_option, delimiter, remove_blank)
2699 /// The last two parameters are optional
2700 ///
2702 void CMacroFunction_SetPubJournal::TheFunction()
2703 {
2704  // can't set journal in the submit-block
2705  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2706  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2707  if (!const_pubdesc)
2708  return;
2709 
2710  size_t index = 0;
2711  const string& newValue = m_Args[index]->GetString();
2712  const string& action_type = m_Args[++index]->GetString();
2713  string delimiter;
2714  bool remove_field = false;
2715  x_GetOptionalArgs(delimiter, remove_field, index);
2717 
2718  CObjectInfo oi = m_DataIter->GetEditedObject();
2721  log << m_DataIter->GetBestDescr();
2722 
2723  if (!newValue.empty()) {
2724  x_SetJournalInPubdesc(*pubdesc, newValue, existing_text);
2725  if (m_QualsChangedCount) {
2726  log << ": set ";
2727  }
2728  }
2729  else if (remove_field) {
2730  x_RemoveJournalInPubdesc(*pubdesc);
2731  if (m_QualsChangedCount) {
2732  log << ": removed ";
2733  }
2734  }
2735 
2736  if (m_QualsChangedCount) {
2737  m_DataIter->SetModified();
2738  log << m_QualsChangedCount << " publication journal ";
2739  x_LogFunction(log);
2740  }
2741 }
2742 
2744 {
2745  auto arg_nr = m_Args.size();
2746  if (arg_nr < 2 || arg_nr > 4) {
2747  return false;
2748  }
2749 
2750  size_t index = 0;
2751  NMacroUtil::GetPrimitiveFromRef(m_Args[index].GetNCObject());
2752  if (!m_Args[index]->IsString()) {
2753  return false;
2754  }
2755  if (!m_Args[++index]->IsString()) return false;
2756  if (arg_nr > 2 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
2757  if (arg_nr > 3 && !m_Args[++index]->IsBool()) return false;
2758  return true;
2759 }
2760 
2762  CPubdesc& pubdesc, const string& newValue, edit::EExistingText existing_text)
2763 {
2764  CTitle* title = nullptr;
2765  for (auto& it : pubdesc.SetPub().Set()) {
2766  switch (it->Which()) {
2767  case CPub::e_Gen:
2768  title = &it->SetGen().SetJournal();
2769  break;
2770  case CPub::e_Article:
2771  title = &it->SetArticle().SetFrom().SetJournal().SetTitle();
2772  break;
2773  case CPub::e_Journal:
2774  title = &it->SetJournal().SetTitle();
2775  default:
2776  break;
2777  }
2778  }
2779 
2780  if (title) {
2781  // if we find a Name, change that
2782  m_QualsChangedCount = 0;
2783  if (title->IsSet()) {
2784  for (auto& it : title->Set()) {
2785  if (it->IsName()) {
2786  string orig_value = it->GetName();
2787  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
2788  it->SetName(orig_value);
2790  }
2791  }
2792  }
2793 
2794  if (m_QualsChangedCount == 0) {
2795  // if we find a not_set, change it to a Name
2796  for (auto& it : title->Set()) {
2797  if (it->Which() == CTitle::C_E::e_not_set) {
2798  it->SetName(newValue);
2800  }
2801  }
2802  }
2803  }
2804 
2805  // otherwise add a Name
2806  if (m_QualsChangedCount == 0) {
2807  CRef<CTitle::C_E> this_title(new CTitle::C_E());
2808  this_title->SetName(newValue);
2809  title->Set().push_back(this_title);
2811  }
2812  }
2813 }
2814 
2816 {
2817  for (auto& it : pubdesc.SetPub().Set()) {
2818  switch (it->Which()) {
2819  case CPub::e_Gen:
2820  if (it->GetGen().IsSetJournal()) {
2821  it->SetGen().ResetJournal();
2823  }
2824  break;
2825  case CPub::e_Article:
2826  if (it->GetArticle().IsSetFrom() &&
2827  it->GetArticle().GetFrom().IsJournal() &&
2828  it->GetArticle().GetFrom().GetJournal().IsSetTitle()) {
2829  it->SetArticle().SetFrom().SetJournal().ResetTitle();
2831  }
2832  break;
2833  case CPub::e_Journal:
2834  if (it->GetJournal().IsSetTitle()) {
2835  it->SetJournal().ResetTitle();
2837  }
2838  default:
2839  break;
2840  }
2841  }
2842 }
2843 
2844 ///////////////////////////////////////////////////////////////////////////////
2845 /// class CMacroFunction_SetPubVolIssuePages
2846 /// SetPubVolume(newValue, existing_text, delimiter, remove_blank)
2847 /// SetPubIssue(newValue, existing_text, delimiter, remove_blank)
2848 /// SetPubPages(newValue, existing_text, delimiter, remove_blank)
2849 /// The last two parameters are optional
2850 ///
2851 const char* CMacroFunction_SetPubVolIssuePages::sm_FuncVolume = "SetPubVolume";
2852 const char* CMacroFunction_SetPubVolIssuePages::sm_FuncIssue = "SetPubIssue";
2853 const char* CMacroFunction_SetPubVolIssuePages::sm_FuncPages = "SetPubPages";
2854 
2856 {
2857  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2858  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2859  if (!const_pubdesc)
2860  return;
2861 
2862  size_t index = 0;
2863  const string& newValue = m_Args[index]->GetString();
2864  const string& action_type = m_Args[++index]->GetString();
2865  string delimiter;
2866  bool remove_field = false;
2867  x_GetOptionalArgs(delimiter, remove_field, index);
2869 
2871  log << m_DataIter->GetBestDescr();
2872  if (!newValue.empty()) {
2873  CObjectInfo oi = m_DataIter->GetEditedObject();
2875  x_SetVolIssuePagesInPubdesc(*pubdesc, newValue, existing_text);
2876 
2877  if (m_QualsChangedCount) {
2878  log << ": set ";
2879  }
2880  }
2881  else if (remove_field) {
2882  CObjectInfo oi = m_DataIter->GetEditedObject();
2885 
2886  if (m_QualsChangedCount) {
2887  log << ": removed ";
2888  }
2889  }
2890 
2891  if (m_QualsChangedCount) {
2892  m_DataIter->SetModified();
2893  log << m_QualsChangedCount << " publication " << m_Field;
2894  x_LogFunction(log);
2895  }
2896 }
2897 
2899 {
2900  auto arg_nr = m_Args.size();
2901  if (arg_nr < 2 || arg_nr > 4) {
2902  return false;
2903  }
2904 
2905  size_t index = 0;
2906  NMacroUtil::GetPrimitiveFromRef(m_Args[index].GetNCObject());
2907  if (!m_Args[index]->IsString()) {
2908  return false;
2909  }
2910  if (!m_Args[++index]->IsString()) return false;
2911  if (arg_nr > 2 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
2912  if (arg_nr > 3 && !m_Args[++index]->IsBool()) return false;
2913  return true;
2914 }
2915 
2917 {
2919 
2920  for (auto& it : pubdesc.SetPub().Set()) {
2921  CObjectInfo pub_oi(it.GetNCPointer(), it->GetThisTypeInfo());
2922  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
2923  switch (it->Which()) {
2924  case CPub::e_Gen:
2925  SetFieldsByName(&objs, pub_var, field);
2926  break;
2927  case CPub::e_Sub:
2928  if (field == "date.std") {
2929  SetFieldsByName(&objs, pub_var, field);
2930  }
2931  break;
2932  case CPub::e_Article:
2933  if (it->GetArticle().IsSetFrom()) {
2934  switch (it->GetArticle().GetFrom().Which()) {
2936  SetFieldsByName(&objs, pub_var, "from.book.imp." + field);
2937  break;
2939  SetFieldsByName(&objs, pub_var, "from.journal.imp." + field);
2940  break;
2942  SetFieldsByName(&objs, pub_var, "from.proc.book.imp." + field);
2943  break;
2944  default:
2945  break;
2946  }
2947  }
2948  break;
2949  case CPub::e_Book:
2950  case CPub::e_Journal:
2951  SetFieldsByName(&objs, pub_var, "imp." + field);
2952  break;
2953  case CPub::e_Man:
2954  SetFieldsByName(&objs, pub_var, "cit.imp." + field);
2955  break;
2956  case CPub::e_Proc:
2957  SetFieldsByName(&objs, pub_var, "book.imp." + field);
2958  break;
2959  default:
2960  break;
2961  }
2962  }
2963  return objs;
2964 }
2965 
2967 {
2969  for (auto& it : objs) {
2972  string orig_value = obj.GetPrimitiveValueString();
2973  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
2974  (SetQualStringValue(obj, orig_value));
2975  }
2976  }
2977  }
2978 }
2979 
2981 {
2984 }
2985 
2986 ///////////////////////////////////////////////////////////////////////////////
2987 // class CMacroFunction_SetPubDate
2988 /// SetPubDate(year, month, date) OR
2989 /// SetPubDate(date_str)
2990 /// The only option is to overwrite
2991 ///
2993 void CMacroFunction_SetPubDate::TheFunction()
2994 {
2995  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
2996  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
2997  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
2998  if (!const_pubdesc && !const_block)
2999  return;
3000 
3001  const string date_field = "date.std";
3002  CObjectInfo oi = m_DataIter->GetEditedObject();
3003  if (const_pubdesc) {
3005  CMQueryNodeValue::TObs objs = s_GetPubVolIssuePagesDateObjects(*pubdesc, date_field);
3006  x_AddDate(objs);
3007  }
3008  else if (const_block) {
3010  if (submit_block->IsSetCit()) {
3012  CObjectInfo sub_oi(&(submit_block->SetCit()), submit_block->SetCit().GetThisTypeInfo());
3013  SetFieldsByName(&objs, sub_oi, date_field);
3014  x_AddDate(objs);
3015  }
3016  }
3017 
3018  if (m_QualsChangedCount) {
3019  m_DataIter->SetModified();
3021  log << m_DataIter->GetBestDescr() << ": set publication date";
3022  x_LogFunction(log);
3023  }
3024 }
3025 
3027 {
3028  auto arg_nr = m_Args.size();
3029  if (arg_nr != 1 && arg_nr != 3) return false;
3030 
3031  if (arg_nr == 1) {
3032  NMacroUtil::GetPrimitiveFromRef(m_Args[0].GetNCObject());
3033  if (!m_Args[0]->IsString())
3034  return false;
3035  }
3036  else {
3037  for (auto& it : m_Args) {
3038  if (!it->IsInt())
3039  return false;
3040  }
3041  }
3042  return true;
3043 }
3044 
3046 {
3047  if (objs.empty()) return;
3048  if (m_Args.size() == 3) {
3049  CObjectInfoMI mem = objs.front().field.BeginMembers();
3050  auto it = m_Args.begin();
3051 
3052  while (mem.Valid() && it != m_Args.end()) {
3053  if ((*it)->GetInt() > 0) {
3054  CObjectInfo tmp(objs.front().field.SetClassMember(mem.GetMemberIndex()));
3055  if (SetSimpleTypeValue(tmp, **it)) {
3057  }
3058  }
3059  ++mem;
3060  ++it;
3061  }
3062  }
3063  else { // date is specified as a string
3064  // if only the year is specified, update the year alone
3065  string orig_date = m_Args[0]->GetString();
3066  CDate_std* date_obj = CTypeConverter<CDate_std>::SafeCast(objs.front().field.GetObjectPtr());
3067  if (!date_obj)
3068  return;
3069 
3070  if (orig_date.length() == 4 && NStr::StringToInt(orig_date, NStr::fConvErr_NoThrow) != 0) {
3071  int year = NStr::StringToInt(orig_date, NStr::fConvErr_NoThrow);
3072  date_obj->SetYear(year);
3074  }
3075  else {
3076  bool ambiguous = false, day_first = false;
3077  CSubSource::DetectDateFormat(orig_date, ambiguous, day_first);
3078  if (!ambiguous) {
3079  bool month_ambiguous = false;
3080  orig_date = CSubSource::FixDateFormat(orig_date, !day_first, month_ambiguous);
3081  }
3082 
3083  auto date = CSubSource::DateFromCollectionDate(orig_date);
3084  CDate_std* date_obj = CTypeConverter<CDate_std>::SafeCast(objs.front().field.GetObjectPtr());
3085  if (date_obj) {
3086  date_obj->Assign(date->GetStd());
3088  }
3089  }
3090  }
3091 }
3092 
3093 ///////////////////////////////////////////////////////////////////////////////
3094 // class CMacroFunction_SetPubDateField
3095 ///SetPubDateField(date_field, new_value, remove_blank)
3096 ///
3099 {
3100  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
3101  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
3102  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
3103  if (!const_pubdesc && !const_block)
3104  return;
3105 
3106  size_t index = 1;
3107  string newValue;
3108  if (m_Args[index]->IsInt()) {
3109  newValue = NStr::Int8ToString(m_Args[index]->GetInt());
3110  }
3111  else if (m_Args[index]->IsString()) {
3112  newValue = m_Args[index]->GetString();
3113  NStr::TruncateSpacesInPlace(newValue);
3114  if (m_Args[0]->GetString() != "season" && !newValue.empty()) {
3115  m_Args[index]->SetInt(NStr::StringToInt8(newValue));
3116  }
3117  }
3118  bool remove_field = (++index < m_Args.size()) ? m_Args[index]->GetBool() : false;
3119 
3121  log << m_DataIter->GetBestDescr();
3122 
3123  const string date_field = "date.std";
3124  CObjectInfo oi = m_DataIter->GetEditedObject();
3125  if (const_pubdesc) {
3127  CMQueryNodeValue::TObs objs = s_GetPubVolIssuePagesDateObjects(*pubdesc, date_field);
3128  if (!newValue.empty()) {
3129  x_AddDateField(objs);
3130  if (m_QualsChangedCount) {
3131  log << ": set ";
3132  }
3133  }
3134  else if (remove_field) {
3135  x_RemoveDateField(objs);
3136  if (m_QualsChangedCount) {
3137  log << ": removed ";
3138  }
3139  }
3140  }
3141  else if (const_block) {
3143  if (submit_block->IsSetCit()) {
3145  CObjectInfo sub_oi(&(submit_block->SetCit()), submit_block->SetCit().GetThisTypeInfo());
3146  if (!newValue.empty()) {
3147  SetFieldsByName(&objs, sub_oi, date_field);
3148  x_AddDateField(objs);
3149  if (m_QualsChangedCount) {
3150  log << ": set ";
3151  }
3152  }
3153  else if (remove_field) {
3154  GetFieldsByName(&objs, sub_oi, date_field);
3155  x_RemoveDateField(objs);
3156  if (m_QualsChangedCount) {
3157  log << ": removed ";
3158  }
3159  }
3160  }
3161  }
3162 
3163  if (m_QualsChangedCount) {
3164  m_DataIter->SetModified();
3165  log << m_QualsChangedCount << " publication " + m_Args[0]->GetString();
3166  x_LogFunction(log);
3167  }
3168 }
3169 
3171 {
3172  if (m_Args.size() != 2 && m_Args.size() != 3) {
3173  return false;
3174  }
3175 
3176  size_t index = 0;
3177  if (!m_Args[index]->IsString()) return false;
3178  NMacroUtil::GetPrimitiveFromRef(m_Args[++index].GetNCObject());
3179  if (!m_Args[index]->IsString() && !m_Args[index]->IsInt()) {
3180  return false;
3181  }
3182  if (++index < m_Args.size() && !m_Args[index]->IsBool()) return false;
3183  return true;
3184 }
3185 
3187 {
3188  if (objs.empty()) return;
3189  CMQueryNodeValue::TObs obj_fields;
3190  SetFieldsByName(&obj_fields, objs.front().field, m_Args[0]->GetString());
3191 
3192  if (!obj_fields.empty() && SetSimpleTypeValue(obj_fields.front().field, *m_Args[1])) {
3194  }
3195 }
3196 
3198 {
3199  if (objs.empty()) return;
3200  CMQueryNodeValue::TObs obj_fields;
3201  GetFieldsByName(&obj_fields, objs.front().field, m_Args[0]->GetString());
3203 }
3204 
3205 ///////////////////////////////////////////////////////////////////////////////
3206 // class CMacroFunction_SetPubCitation
3207 /// SetPubCitation(newValue, existingtext_option, delimiter, remove_blank)
3208 ///
3209 
3210 DEFINE_MACRO_FUNCNAME(CMacroFunction_SetPubCitation, "SetPubCitation")
3211 void CMacroFunction_SetPubCitation::TheFunction()
3212 {
3213  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
3214  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
3215  if (!const_pubdesc)
3216  return;
3217 
3218  size_t index = 0;
3219  const string& newValue = m_Args[index]->GetString();
3220  const string& action_type = m_Args[++index]->GetString();
3221  string delimiter;
3222  bool remove_field = false;
3223  x_GetOptionalArgs(delimiter, remove_field, index);
3225 
3226  CObjectInfo oi = m_DataIter->GetEditedObject();
3228 
3230  log << m_DataIter->GetBestDescr();
3231 
3232  if (!newValue.empty()) {
3234  for (auto& it : pubdesc->SetPub().Set()) {
3235  CObjectInfo pub_oi(it.GetNCPointer(), it->GetThisTypeInfo());
3236  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
3237  switch (it->Which()) {
3238  case CPub::e_Gen:
3239  SetFieldsByName(&objs, pub_var, "cit");
3240  break;
3241  default:
3242  break;
3243  }
3244  }
3245 
3246  for (auto& it : objs) {
3249  string orig_value = obj.GetPrimitiveValueString();
3250  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
3251  (SetQualStringValue(obj, orig_value));
3252  }
3253  }
3254  }
3255 
3256  if (m_QualsChangedCount) {
3257  log << ": set ";
3258  }
3259  }
3260  else if (remove_field) {
3262  for (auto& it : pubdesc->SetPub().Set()) {
3263  CObjectInfo pub_oi(it.GetNCPointer(), it->GetThisTypeInfo());
3264  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
3265  switch (it->Which()) {
3266  case CPub::e_Gen:
3267  GetFieldsByName(&objs, pub_var, "cit");
3268  break;
3269  default:
3270  break;
3271  }
3272  }
3273  m_QualsChangedCount = CMacroFunction_RemoveQual::s_RemoveFields(m_DataIter, objs);
3274  if (m_QualsChangedCount) {
3275  log << ": removed ";
3276  }
3277 
3278  }
3279  if (m_QualsChangedCount) {
3280  m_DataIter->SetModified();
3281  log << m_QualsChangedCount << " publication citation";
3282  x_LogFunction(log);
3283  }
3284 }
3285 
3286 bool CMacroFunction_SetPubCitation::x_ValidArguments() const
3287 {
3288  auto arg_nr = m_Args.size();
3289  if (arg_nr < 2 || arg_nr > 4) {
3290  return false;
3291  }
3292  size_t index = 0;
3293  NMacroUtil::GetPrimitiveFromRef(m_Args[index].GetNCObject());
3294  if (!m_Args[index]->IsString() || !m_Args[++index]->IsString()) {
3295  return false;
3296  }
3297  if (arg_nr > 2 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
3298  if (arg_nr > 3 && !m_Args[++index]->IsBool()) return false;
3299  return true;
3300 }
3301 
3302 
3303 ///////////////////////////////////////////////////////////////////////////////
3304 // class CMacroFunction_SetSerialNumber
3305 /// SetPubSerialNumber(number, existing_text_option, delimiter, remove_blank)
3306 DEFINE_MACRO_FUNCNAME(CMacroFunction_SetSerialNumber, "SetPubSerialNumber")
3307 void CMacroFunction_SetSerialNumber::TheFunction()
3308 {
3309  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
3310  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
3311  if (!const_pubdesc)
3312  return;
3313 
3314  size_t index = 0;
3315  string newValue;
3316  if (m_Args[index]->IsString()) {
3317  newValue = m_Args[0]->GetString();
3318  }
3319  else if (m_Args[index]->IsInt()) {
3320  newValue = NStr::Int8ToString(m_Args[index]->GetInt(), NStr::fConvErr_NoThrow);
3321  if (errno != 0)
3322  return;
3323  }
3324 
3325  const string& action_type = m_Args[++index]->GetString();
3326  string delimiter;
3327  bool remove_field = false;
3328  x_GetOptionalArgs(delimiter, remove_field, index);
3330 
3331  CObjectInfo oi = m_DataIter->GetEditedObject();
3333 
3335  log << m_DataIter->GetBestDescr();
3336 
3337  if (!newValue.empty()) {
3339  for (auto& it : pubdesc->SetPub().Set()) {
3340  CObjectInfo pub_oi(it.GetNCPointer(), it->GetThisTypeInfo());
3341  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
3342  switch (it->Which()) {
3343  case CPub::e_Gen:
3344  SetFieldsByName(&objs, pub_var, "serial-number");
3345  break;
3346  default:
3347  break;
3348  }
3349  }
3350 
3351  for (auto& it : objs) {
3355  if (errno != 0) {
3356  continue;
3357  }
3358  if (edit::AddValueToString(orig_value, newValue, existing_text)) {
3359  int new_int_value = NStr::StringToInt(orig_value, NStr::fConvErr_NoThrow);
3360  if (errno == 0 && new_int_value != obj.GetPrimitiveValueInt()) {
3361  obj.SetPrimitiveValueInt(new_int_value);
3362  m_QualsChangedCount++;
3363  }
3364  }
3365  }
3366  }
3367  if (m_QualsChangedCount) {
3368  log << ": set ";
3369  }
3370  }
3371  else if (remove_field) {
3373  for (auto& it : pubdesc->SetPub().Set()) {
3374  CObjectInfo pub_oi(it.GetNCPointer(), it->GetThisTypeInfo());
3375  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
3376  switch (it->Which()) {
3377  case CPub::e_Gen:
3378  GetFieldsByName(&objs, pub_var, "serial-number");
3379  break;
3380  default:
3381  break;
3382  }
3383  }
3384  m_QualsChangedCount = CMacroFunction_RemoveQual::s_RemoveFields(m_DataIter, objs);
3385  if (m_QualsChangedCount) {
3386  log << ": removed ";
3387  }
3388 
3389  }
3390  if (m_QualsChangedCount) {
3391  m_DataIter->SetModified();
3392  log << m_QualsChangedCount << " publication serial number";
3393  x_LogFunction(log);
3394  }
3395 }
3396 
3397 bool CMacroFunction_SetSerialNumber::x_ValidArguments() const
3398 {
3399  auto arg_nr = m_Args.size();
3400  if (arg_nr > 4 || arg_nr < 2) {
3401  return false;
3402  }
3403  size_t index = 0;
3404  NMacroUtil::GetPrimitiveFromRef(m_Args[index].GetNCObject());
3405  if (!m_Args[index]->IsInt() && !m_Args[index]->IsString())
3406  return false;
3407 
3408  if (!m_Args[++index]->IsString()) return false;
3409  if (arg_nr > 2 && (!m_Args[++index]->IsString() && !m_Args[index]->IsBool())) return false;
3410  if (arg_nr > 3 && !m_Args[++index]->IsBool()) return false;
3411  return true;
3412 }
3413 
3414 
3415 ///////////////////////////////////////////////////////////////////////////////
3416 // class CMacroFunction_SetPubStatus
3417 /// SetPubStatus(value)
3418 ///
3420 void CMacroFunction_SetPubStatus::TheFunction()
3421 {
3422  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
3423  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
3424  if (!const_pubdesc)
3425  return;
3426 
3427  CObjectInfo oi = m_DataIter->GetEditedObject();
3428  if (const_pubdesc) {
3430  if (s_SetStatus(*pubdesc, m_Args[0]->GetString()))
3431  m_QualsChangedCount++;
3432  }
3433 
3434  if (m_QualsChangedCount) {
3435  m_DataIter->SetModified();
3437  log << m_DataIter->GetBestDescr() << ": set publication status";
3438  x_LogFunction(log);
3439  }
3440 }
3441 
3443 {
3444  return (m_Args.size() == 1 && m_Args[0]->IsString());
3445 }
3446 
3448 {
3451  return false;
3452  }
3453 
3454  bool rval = false;
3455  for (auto&& it: pubdesc.SetPub().Set()) {
3456  rval |= x_SetStatus(*it, status);
3457  }
3458  return rval;
3459 }
3460 
3462 {
3464  return false;
3465  }
3467  if (status == curr_status) {
3468  return false;
3469  }
3470 
3471  bool rval = false;
3473  if (old_imp) {
3474  CRef<CImprint> new_imp(new CImprint());
3475  new_imp->Assign(*old_imp);
3476  switch (status) {
3479  rval = true;
3480  break;
3482  new_imp->ResetPrepub();
3483  rval = true;
3484  break;
3487  rval = true;
3488  break;
3489  default:
3490  break;
3491  }
3492  if (rval) {
3493  CPubFieldType::SetImprint(pub, *new_imp);
3494  }
3495  }
3496  else if (pub.IsGen()) {
3498  pub.SetGen().SetCit("unpublished");
3499  rval = true;
3500  }
3501  else if (status == CPubFieldType::ePubFieldStatus_Published) {
3502  pub.SetGen().ResetCit();
3503  rval = true;
3504  }
3505  else if (status == CPubFieldType::ePubFieldStatus_InPress) {
3506  // transform it to an article
3507  CPub tmp_pub;
3508  tmp_pub.Assign(pub);
3509 
3510  pub.Reset();
3511  auto& article = pub.SetArticle();
3512  auto& cit_gen = tmp_pub.GetGen();
3513 
3514  if (cit_gen.IsSetTitle()) {
3515  CRef<CTitle::C_E> new_title(new CTitle::C_E());
3516  new_title->SetName(cit_gen.GetTitle());
3517  article.SetTitle().Set().push_back(new_title);
3518  }
3519  if (cit_gen.IsSetAuthors()) {
3520  article.SetAuthors().Assign(cit_gen.GetAuthors());
3521  }
3522 
3523  auto& journal = article.SetFrom().SetJournal();
3524  journal.SetImp().SetPrepub(CImprint::ePrepub_in_press);
3525 
3526  // the journal title must be specified
3527  if (cit_gen.IsSetJournal()) {
3528  journal.SetTitle().Assign(cit_gen.GetJournal());
3529  }
3530  else {
3531  CRef<CTitle::C_E> new_title(new CTitle::C_E());
3532  new_title->SetName(kEmptyStr);
3533  journal.SetTitle().Set().push_back(new_title);
3534  }
3535 
3536  // date must be also specified
3537  if (cit_gen.IsSetDate()) {
3538  journal.SetImp().SetDate().Assign(cit_gen.GetDate());
3539  }
3540  else {
3541  CRef<CDate> today(new CDate);
3543  auto year = today->GetStd().GetYear();
3544  journal.SetImp().SetDate().SetStd().SetYear(year);
3545  }
3546 
3547  if (cit_gen.IsSetVolume()) {
3548  journal.SetImp().SetVolume(cit_gen.GetVolume());
3549  }
3550  if (cit_gen.IsSetIssue()) {
3551  journal.SetImp().SetIssue(cit_gen.GetIssue());
3552  }
3553  if (cit_gen.IsSetPages()) {
3554  journal.SetImp().SetPages(cit_gen.GetPages());
3555  }
3556  rval = true;
3557  }
3558  }
3559  return rval;
3560 }
3561 
3562 ///////////////////////////////////////////////////////////////////////////////
3563 /// class CMacroFunction_SetPubPMID
3564 /// SetPMID(pmid_value, remove_blank);
3565 ///
3566 DEFINE_MACRO_FUNCNAME(CMacroFunction_SetPubPMID, "SetPMID")
3567 void CMacroFunction_SetPubPMID::TheFunction()
3568 {
3569  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
3570  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
3571  if (!const_pubdesc) return;
3572 
3573  CObjectInfo oi = m_DataIter->GetEditedObject();
3575  _ASSERT(pubdesc);
3576 
3577  string newStrValue;
3578  TEntrezId new_pmid = ZERO_ENTREZ_ID;
3579  size_t index = 0;
3580  if (m_Args[index]->IsString()) {
3581  newStrValue = m_Args[index]->GetString();
3582  NStr::TruncateSpacesInPlace(newStrValue);
3583  TIntId converted_id = NStr::StringToInt8(newStrValue, NStr::fConvErr_NoThrow);
3584  new_pmid = ENTREZ_ID_FROM(TIntId, converted_id);
3585  }
3586  else if (m_Args[index]->GetInt()) {
3587  TIntId id = m_Args[index]->GetInt();
3588  new_pmid = ENTREZ_ID_FROM(TIntId, id);
3589  newStrValue = NStr::NumericToString(new_pmid);
3590  }
3591  bool remove_field = (++index < m_Args.size()) ? m_Args[index]->GetBool() : false;
3592 
3594  log << m_DataIter->GetBestDescr();
3595 
3596  if (!newStrValue.empty()) {
3597  bool has_pmid = false;
3598  for (auto& it : pubdesc->SetPub().Set()) {
3599  if (it->IsPmid()) {
3600  has_pmid = true;
3601  it->SetPmid().Set(new_pmid);
3602  m_QualsChangedCount++;
3603  break;
3604  }
3605  }
3606 
3607  // don't add pmids to cit-subs
3608  for (auto& it : pubdesc->GetPub().Get()) {
3609  if (it->IsSub()) {
3610  return;
3611  }
3612  }
3613 
3614  if (!has_pmid) {
3615  CRef<CPub> new_pub(new CPub());
3616  new_pub->SetPmid().Set(new_pmid);
3617  pubdesc->SetPub().Set().push_back(new_pub);
3618  m_QualsChangedCount++;
3619  }
3620 
3621  // update the cit-art
3622  bool has_art_pmid = false;
3623  for (auto& it : pubdesc->SetPub().Set()) {
3624  if (it->IsArticle()) {
3625  if (it->SetArticle().IsSetIds()) {
3626  EDIT_EACH_ARTICLEID_ON_CITART(id, it->SetArticle()) {
3627  if ((*id)->IsPubmed()) {
3628  has_art_pmid = true;
3629  (*id)->SetPubmed().Set(new_pmid);
3630  m_QualsChangedCount++;
3631  }
3632  }
3633  }
3634 
3635  if (!has_art_pmid) {
3636  CRef<CArticleId> art_id(new CArticleId);
3637  art_id->SetPubmed().Set(new_pmid);
3638  it->SetArticle().SetIds().Set().push_back(art_id);
3639  m_QualsChangedCount++;
3640  }
3641  }
3642  }
3643  if (m_QualsChangedCount) {
3644  log << ": applied pmid " << new_pmid;
3645  }
3646  }
3647  else if (remove_field) {
3648  CPub_equiv::Tdata::iterator pub_it = pubdesc->SetPub().Set().begin();
3649  while (pub_it != pubdesc->SetPub().Set().end()) {
3650  auto& pub_elem = (*pub_it);
3651  if (pub_elem->IsPmid()) {
3652  pub_it = pubdesc->SetPub().Set().erase(pub_it);
3653  m_QualsChangedCount++;
3654  continue;
3655  }
3656  else if (pub_elem->IsArticle() && pub_elem->GetArticle().IsSetIds()) {
3657  EDIT_EACH_ARTICLEID_ON_CITART(id, pub_elem->SetArticle()) {
3658  if ((*id)->IsPubmed()) {
3659  ERASE_ARTICLEID_ON_CITART(id, pub_elem->SetArticle());
3660  m_QualsChangedCount++;
3661  }
3662  }
3663  if (pub_elem->GetArticle().GetIds().Get().empty()) {
3664  pub_elem->SetArticle().ResetIds();
3665  }
3666  }
3667  ++pub_it;
3668  }
3669  if (m_QualsChangedCount) {
3670  log << ": removed pmid";
3671  }
3672  }
3673  if (m_QualsChangedCount) {
3674  m_DataIter->SetModified();
3675  x_LogFunction(log);
3676  }
3677 }
3678 
3679 bool CMacroFunction_SetPubPMID::x_ValidArguments() const
3680 {
3681  if (m_Args.empty() || m_Args.size() > 2) {
3682  return false;
3683  }
3684  NMacroUtil::GetPrimitiveFromRef(m_Args[0].GetNCObject());
3685  if (!m_Args[0]->IsInt() && !m_Args[0]->IsString())
3686  return false;
3687  if (m_Args.size() == 2 && !m_Args[1]->IsBool())
3688  return false;
3689  return true;
3690 }
3691 
3693 
3694 static CRef<CSeqdesc> s_MakeNewPubdesc(CRef<CPub>& new_pub, TEntrezId pmid);
3695 
3696 ///////////////////////////////////////////////////////////////////////////////
3697 /// class CMacroFunction_ApplyPmidToEntry
3698 /// ApplyPmidToEntry(pmid [,to_multiple_bioseqs(bool)])
3699 /// The macro checks all references in the record (usually a seq-entry containing a single bioseq).
3700 /// If the new pmid already exists in the entry, it does nothing. If the new pmid does not exist in the entry,
3701 /// it applies it as a new pubdesc descriptor containing this single pmid pub. This is to be done even if there is another pmid.
3702 /// At the end it does a pub lookup.
3703 /// If the second argument is missing or it's 'false' the macro applies the PMID only to a seq-entry that is a single bioseq
3704 /// Otherwise, it adds it to all bioseqs within the entry
3705 
3706 DEFINE_MACRO_FUNCNAME(CMacroFunction_ApplyPmidToEntry, "ApplyPmidToEntry")
3707 void CMacroFunction_ApplyPmidToEntry::TheFunction()
3708 {
3709  // the iterator should iterate over TSEntry
3710  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
3711  const CSeq_entry* entry = dynamic_cast<const CSeq_entry*>(obj.GetPointer());
3712  if (!entry) {
3713  return;
3714  }
3715 
3716  // we assume that the TSEntry has only one nucleotide sequence
3717  size_t count = 0;
3718  CBioseq_CI b_iter(m_DataIter->GetSEH(), CSeq_inst::eMol_na);
3719  CBioseq_Handle bsh = *b_iter;
3720  for (; b_iter; ++b_iter) {
3721  ++count;
3722  }
3723 
3724 
3725  bool multiple = (m_Args.size() == 2) ? m_Args[1]->GetBool() : false;
3726  if (count != 1 && !multiple) {
3728  log << "Pmid " << m_Args[0]->GetInt() << " was not applied as the record has " << count << " nucleotide sequences. ";
3729  x_LogError(log);
3730  return;
3731  }
3732 
3733  TEntrezId new_pmid = ZERO_ENTREZ_ID;
3734  TIntId id = m_Args[0]->GetInt();
3735  new_pmid = ENTREZ_ID_FROM(TIntId, id);
3736  CRef<CPub> new_pub(nullptr);
3737 
3738  if (m_DataIter->IsHugeDataMode()) {
3739  if (auto& remote_updater = m_DataIter->RemoteUpdater(); remote_updater) {
3740  CPub pmid_pub;
3741  pmid_pub.SetPmid().Set(new_pmid);
3742 
3743  CPubdesc pubdesc;
3744  pubdesc.SetPub().Set().emplace_back(&pmid_pub);
3745 
3746  CSeqdesc desc;
3747  desc.SetPub(pubdesc);
3748 
3749  CPubdesc tmp_pubdesc;
3750  tmp_pubdesc.Assign(pubdesc);
3751 
3752  remote_updater->UpdatePubReferences(desc);
3753  AdjustAuthors(pubdesc);
3754 
3755  if (!pubdesc.Equals(tmp_pubdesc)) {
3756  m_QualsChangedCount++;
3757  new_pub.Reset(new CPub);
3758  for (const auto& pub_it : pubdesc.GetPub().Get()) {
3759  if (!pub_it->IsPmid()) {
3760  new_pub->Assign(*pub_it);
3761  break;
3762  }
3763  }
3764  }
3765  // TODO - better error handling
3766  }
3767  }
3768  else {
3770  }
3771 
3772  if (!new_pub) {
3774  log << new_pmid << " pmid failed to look up";
3775  x_LogError(log);
3776  return;
3777  }
3778 
3779  if (!multiple) {
3780  set<TEntrezId> orig_pmids = s_GatherExistingPMIDs(bsh);
3781 
3782  // don't update if the new_pmid is already in the entry
3783  if (orig_pmids.find(new_pmid) != orig_pmids.end()) {
3784  return;
3785  }
3786 
3787  CRef<CSeqdesc> new_desc = s_MakeNewPubdesc(new_pub, new_pmid);
3788  CRef<CCmdComposite> add_cmd(new CCmdComposite("Create new pmid pub"));
3789  add_cmd->AddCommand(*CRef<CCmdCreateDesc>(new CCmdCreateDesc(bsh.GetSeq_entry_Handle(), *new_desc)));
3790  if (add_cmd) {
3791  m_DataIter->RunCommand(add_cmd, m_CmdComposite);
3792 
3793  string best_id;
3794  CWriteUtil::GetBestId(bsh.GetAccessSeq_id_Handle(), m_DataIter->GetSEH().GetScope(), best_id);
3795 
3797  log << "Applied " << new_pmid << " pmid to " << best_id;
3798  x_LogFunction(log);
3799  }
3800  }
3801  else { // update each nucleotide sequence
3802  unsigned seq_nr = 0;
3803  CSeq_entry_Handle seh = m_DataIter->GetSEH();
3804  for (CBioseq_CI b_iter(seh, CSeq_inst::eMol_na); b_iter; ++b_iter)
3805  {
3806  set<TEntrezId> orig_pmids = s_GatherExistingPMIDs(*b_iter);
3807 
3808  // don't update if the new_pmid is already present on the bioseq
3809  if (orig_pmids.find(new_pmid) != orig_pmids.end()) {
3810  continue;
3811  }
3812 
3813  CSeq_entry_Handle entry_handle = b_iter->GetSeq_entry_Handle();
3814  CBioseq_set_Handle bssh = b_iter->GetParentBioseq_set();
3815  if (bssh && bssh.IsSetClass() && bssh.GetClass() == CBioseq_set::eClass_nuc_prot) {
3816  entry_handle = bssh.GetParentEntry();
3817  }
3818 
3819  CRef<CPub> pub(new CPub);
3820  pub->Assign(*new_pub);
3821  CRef<CSeqdesc> new_desc = s_MakeNewPubdesc(pub, new_pmid);
3822 
3823  CRef<CCmdComposite> add_cmd(new CCmdComposite("Create new pmid pub"));
3824  add_cmd->AddCommand(*CRef<CCmdCreateDesc>(new CCmdCreateDesc(entry_handle, *new_desc)));
3825  if (add_cmd) {
3826  m_DataIter->RunCommand(add_cmd, m_CmdComposite);
3827  seq_nr++;
3828  }
3829  }
3830 
3831  if (seq_nr > 0) {
3832  if (m_DataIter->IsHugeDataMode()) {
3833  TChangedQuals report;
3834  Int8 int_pmid = ENTREZ_ID_TO(Int8, new_pmid);
3835  string msg = NStr::Int8ToString(int_pmid) + " pmid lookup";
3836  report[msg] = m_QualsChangedCount;
3837  CRef<IFunctionLog> fnc_log(new CGeneralFuncLog(report));
3838  x_LogChangedQuals(fnc_log);
3839  }
3840  else {
3842  log << "Applied " << new_pmid << " pmid to " << seq_nr << " sequences";
3843  x_LogFunction(log);
3844  }
3845  }
3846  }
3847 
3848 }
3849 
3850 bool CMacroFunction_ApplyPmidToEntry::x_ValidArguments() const
3851 {
3852  if (m_Args.size() != 1 && m_Args.size() != 2)
3853  return false;
3854 
3855  return (m_Args[0]->IsInt() && (m_Args.size() == 2) ? m_Args[1]->IsBool() : true);
3856 }
3857 
3859 {
3860  set<TEntrezId> pmids;
3861  for (CSeqdesc_CI desc_it(bsh, CSeqdesc::e_Pub); desc_it; ++desc_it) {
3862  const CPubdesc& pub = desc_it->GetPub();
3863  for (auto& it : pub.GetPub().Get()) {
3864  if (it->IsPmid()) {
3865  pmids.insert(it->GetPmid().Get());
3866  }
3867  if (it->IsArticle() && it->GetArticle().IsSetIds()) {
3868  FOR_EACH_ARTICLEID_ON_CITART(id, it->GetArticle()) {
3869  if ((*id)->IsPubmed()) {
3870  pmids.insert((*id)->GetPubmed().Get());
3871  }
3872  }
3873  }
3874  if (it->IsMedline() && it->GetMedline().IsSetPmid()) {
3875  pmids.insert(it->GetMedline().GetPmid().Get());
3876  }
3877  }
3878  }
3879  return pmids;
3880 }
3881 
3883 {
3884  CRef<CPubdesc> new_pubdesc(new CPubdesc);
3885 
3886  CRef<CPub> pmid_pub(new CPub());
3887  pmid_pub->SetPmid().Set(pmid);
3888  new_pubdesc->SetPub().Set().push_back(pmid_pub);
3889  new_pubdesc->SetPub().Set().push_back(new_pub);
3890 
3891  CRef<CSeqdesc> new_desc(new CSeqdesc);
3892  new_desc->SetPub(*new_pubdesc);
3893  return new_desc;
3894 }
3895 
3897 
3898 ///////////////////////////////////////////////////////////////////////////////
3899 /// class CMacroFunction_ApplyDOIToEntry
3900 /// ApplyDOIToEntry(doi_name [,to_multiple_bioseqs(bool)]);/
3901 /// The macro checks all references in the record (usually a seq-entry containing a single bioseq).
3902 /// If the new doi number already exists in the entry, it does nothing. Otherwise, it looks up the doi_name and
3903 /// and adds the reference to the entry.
3904 /// If the second argument is missing or it's 'false' the macro applies the PMID only to a seq-entry that is a single bioseq
3905 /// Otherwise, it adds it to all bioseqs within the entry
3906 DEFINE_MACRO_FUNCNAME(CMacroFunction_ApplyDOIToEntry, "ApplyDOIToEntry")
3907 
3908 void CMacroFunction_ApplyDOIToEntry::TheFunction()
3909 {
3910  // the iterator should iterate over TSEntry
3911  CConstRef<CObject> obj = m_DataIter->GetScopedObject().object;
3912  const CSeq_entry* entry = dynamic_cast<const CSeq_entry*>(obj.GetPointer());
3913  if (!entry) {
3914  return;
3915  }
3916 
3917  // we assume that the TSEntry has only one nucleotide sequence
3918  size_t count = 0;
3919  CBioseq_CI b_iter(m_DataIter->GetSEH(), CSeq_inst::eMol_na);
3920  CBioseq_Handle bsh = *b_iter;
3921  for (; b_iter; ++b_iter) {
3922  ++count;
3923  }
3924 
3925  const string& new_doi = m_Args[0]->GetString();
3926  bool multiple = (m_Args.size() == 2) ? m_Args[1]->GetBool() : false;
3927  if (count != 1 && !multiple) {
3929  log << "DOI " << new_doi << " was not applied as the record has " << count << " nucleotide sequences. ";
3930  x_LogError(log);
3931  return;
3932  }
3933 
3934  pair<CRef<CPubdesc>, string> new_pubdesc_str;
3935 
3936  if (m_DataIter->IsHugeDataMode()) {
3937  if (auto& doi_updater = m_DataIter->DOIUpdater(); doi_updater) {
3938  new_pubdesc_str = doi_updater->GetPub(new_doi);
3939  }
3940  }
3941  else {
3942  new_pubdesc_str = CDoiLookup::GetPubFromCrossRef(new_doi);
3943  }
3944 
3945  CRef<CPubdesc> new_pubdesc = new_pubdesc_str.first;
3946  if (!new_pubdesc) {
3948  log << "Failed to resolve DOI " << new_doi << ": " << new_pubdesc_str.second;
3949  x_LogError(log);
3950  return;
3951  }
3952 
3953  if (!multiple) {
3954  set<string> orig_dois = s_GatherExistingDOIs(bsh);
3955 
3956  // don't update if the new_doi is already in the entry
3957  if (orig_dois.find(new_doi) != orig_dois.end()) {
3958  return;
3959  }
3960 
3961  CRef<CSeqdesc> new_desc(new CSeqdesc);
3962  new_desc->SetPub(*new_pubdesc);
3963 
3964  CRef<CCmdComposite> add_cmd(new CCmdComposite("Create new pubdesc based on doi"));
3965  add_cmd->AddCommand(*CRef<CCmdCreateDesc>(new CCmdCreateDesc(bsh.GetSeq_entry_Handle(), *new_desc)));
3966  if (add_cmd) {
3967  m_DataIter->RunCommand(add_cmd, m_CmdComposite);
3968 
3969  string best_id;
3970  CWriteUtil::GetBestId(bsh.GetAccessSeq_id_Handle(), m_DataIter->GetSEH().GetScope(), best_id);
3971 
3973  log << "Applied publication with " << new_doi << " doi to " << best_id;
3974  x_LogFunction(log);
3975  }
3976  }
3977  else { // update each nucleotide sequence
3978  unsigned seq_nr = 0;
3979  CSeq_entry_Handle seh = m_DataIter->GetSEH();
3980  for (CBioseq_CI b_iter(seh, CSeq_inst::eMol_na); b_iter; ++b_iter)
3981  {
3982  set<string> orig_dois = s_GatherExistingDOIs(*b_iter);
3983 
3984  // don't update if the new_pmid is already present on the bioseq
3985  if (orig_dois.find(new_doi) != orig_dois.end()) {
3986  continue;
3987  }
3988 
3989  CSeq_entry_Handle entry_handle = b_iter->GetSeq_entry_Handle();
3990  CBioseq_set_Handle bssh = b_iter->GetParentBioseq_set();
3991  if (bssh && bssh.IsSetClass() && bssh.GetClass() == CBioseq_set::eClass_nuc_prot) {
3992  entry_handle = bssh.GetParentEntry();
3993  }
3994 
3995  CRef<CSeqdesc> new_desc(new CSeqdesc);
3996  new_desc->SetPub(*new_pubdesc);
3997 
3998  CRef<CCmdComposite> add_cmd(new CCmdComposite("Create new pubdesc based on doi"));
3999  add_cmd->AddCommand(*CRef<CCmdCreateDesc>(new CCmdCreateDesc(entry_handle, *new_desc)));
4000  if (add_cmd) {
4001  m_DataIter->RunCommand(add_cmd, m_CmdComposite);
4002  seq_nr++;
4003  }
4004  }
4005 
4006  if (seq_nr > 0) {
4007  if (m_DataIter->IsHugeDataMode()) {
4008  TChangedQuals report;
4009  report[new_doi + " DOI lookup"] = seq_nr;
4010  CRef<IFunctionLog> fnc_log(new CGeneralFuncLog(report));
4011  x_LogChangedQuals(fnc_log);
4012  }
4013  else {
4015  log << "Applied " << new_doi << " DOI to " << seq_nr << " sequences";
4016  x_LogFunction(log);
4017  }
4018  }
4019  }
4020 }
4021 
4022 bool CMacroFunction_ApplyDOIToEntry::x_ValidArguments() const
4023 {
4024  if (m_Args.size() != 1 && m_Args.size() != 2)
4025  return false;
4026 
4027  return (m_Args[0]->IsString() && (m_Args.size() == 2) ? m_Args[1]->IsBool() : true);
4028 }
4029 
4031 {
4032  set<string> dois;
4033  for (CSeqdesc_CI desc_it(bsh, CSeqdesc::e_Pub); desc_it; ++desc_it) {
4034  const CPubdesc& pub = desc_it->GetPub();
4035  for (auto& it : pub.GetPub().Get()) {
4036  if (it->IsArticle() && it->GetArticle().IsSetIds()) {
4037  FOR_EACH_ARTICLEID_ON_CITART(id, it->GetArticle()) {
4038  if ((*id)->IsDoi()) {
4039  dois.insert((*id)->GetDoi());
4040  }
4041  }
4042  }
4043  }
4044  }
4045  return dois;
4046 }
4047 
4048 ///////////////////////////////////////////////////////////////////////////////
4049 /// class CMacroFunction_RemovePubAuthors
4050 /// RemovePubAuthors() - removes the author name list (considered to be one field)
4051 ///
4052 DEFINE_MACRO_FUNCNAME(CMacroFunction_RemovePubAuthors, "RemoveAuthors")
4053 void CMacroFunction_RemovePubAuthors::TheFunction()
4054 {
4055  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
4056  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
4057  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
4058  if (!const_pubdesc && !const_block)
4059  return;
4060 
4061  bool modified = false;
4062  CObjectInfo oi = m_DataIter->GetEditedObject();
4063  if (const_pubdesc) {
4065  for (auto& it : pubdesc->SetPub().Set()) {
4066  if (it->IsSetAuthors()) {
4067  CAuth_list& auth_list = it->SetAuthors();
4068  auth_list.ResetNames();
4069  auth_list.SetNames().SetStr().push_back("?");
4070  modified = true;
4071  }
4072  break;
4073  }
4074  }
4075  else if (const_block) {
4077  if (submit_block->IsSetCit() && submit_block->SetCit().IsSetAuthors()) {
4078  submit_block->SetCit().SetAuthors().ResetNames();
4079  submit_block->SetCit().SetAuthors().SetNames().SetStr().push_back("?");
4080  modified = true;
4081  }
4082  }
4083 
4084  if (modified) {
4085  m_DataIter->SetModified();
4087  log << m_DataIter->GetBestDescr() << ": removed publication authors";
4088  x_LogFunction(log);
4089  }
4090 }
4091 
4092 bool CMacroFunction_RemovePubAuthors::x_ValidArguments() const
4093 {
4094  return m_Args.empty();
4095 }
4096 
4097 
4098 ///////////////////////////////////////////////////////////////////////////////
4099 // class CMacroFunction_RemovePubAuthorMI
4100 /// RemovePubAuthorMI(author_object)
4101 ///
4102 DEFINE_MACRO_FUNCNAME(CMacroFunction_RemovePubAuthorMI, "RemovePubAuthorMI")
4103 void CMacroFunction_RemovePubAuthorMI::TheFunction()
4104 {
4105  CConstRef<CObject> object = m_DataIter->GetScopedObject().object;
4106  const CPubdesc* const_pubdesc = dynamic_cast<const CPubdesc*>(object.GetPointer());
4107  const CSubmit_block* const_block = dynamic_cast<const CSubmit_block*>(object.GetPointer());
4108  if (!const_pubdesc && !const_block)
4109  return;
4110 
4111  CMQueryNodeValue::TObs res_oi;
4112  if (m_Args[0]->AreObjects()) {
4113  res_oi = m_Args[0]->GetObjects();
4114  }
4115  else if (m_Args[0]->IsRef()) {
4116  x_GetObjectsFromRef(res_oi, 0);
4117  }
4118 
4119  if (res_oi.empty()) {
4120  return;
4121  }
4122 
4123  for(auto&& it : res_oi) {
4124  // it can be either CName_std object or a string
4125  if (it.field.GetTypeFamily() == eTypeFamilyPrimitive) {
4126  return;
4127  }
4128  else {
4129  CName_std* std_name = CTypeConverter<CName_std>::SafeCast(it.field.GetObjectPtr());
4130  if (std_name && NMacroUtil::RemoveMiddleInitial(*std_name)) {
4131  m_QualsChangedCount++;
4132  }
4133  }
4134  }
4135 
4136  if (m_QualsChangedCount) {
4137  m_DataIter->SetModified();
4139  log << m_DataIter->GetBestDescr() << ": removed " << m_QualsChangedCount << " publication author middle initial";
4140  x_LogFunction(log);
4141  }
4142 }
4143 
4144 bool CMacroFunction_RemovePubAuthorMI::x_ValidArguments() const
4145 {
4146  if (m_Args.size() != 1) {
4147  return false;
4148  }
4149  return (m_Args[0]->AreObjects() || m_Args[0]->IsRef());
4150 }
4151 
4152 ///////////////////////////////////////////////////////////////////////////////
4153 /// class CMacroFunction_SetPubField
4154 /// SetPub_Date(year, month, day, season, hour, minute, second);
4155 /// SetPub_Affil(affil_field, new_value);
4156 /// All parameters except the first one is optional
4157 
4158 /// DEPRECATED functions
4159 const char* CMacroFunction_SetPubAffil_Depr::sm_FunctionName = "SetPub_Affil";
4160 const char* CMacroFunction_SetPubDate_Depr::sm_FunctionName = "SetPub_Date";
4161 
4163 {
4164  CObjectInfo oi = m_DataIter->GetEditedObject();
4165  CMQueryNodeValue::TObs res_oi;
4166  // it will not set new field in the submitter block
4167  if (!GetFieldsByName(&res_oi, oi, "pub..") || res_oi.size() != 1)
4168  return;
4169 
4170  CObjectInfo current_oi = res_oi.front().field;
4171  if (current_oi.GetTypeFamily() == eTypeFamilyPointer) {
4172  current_oi = current_oi.GetPointedObject();
4173  }
4174 
4175  if (current_oi.GetTypeFamily() != eTypeFamilyContainer)
4176  return;
4177 
4178  // res_oi should be a container of pointers, each of them pointing to a Pub field
4179  CObjectInfoEI elem = current_oi.BeginElements();
4180  while (elem.Valid()) {
4181  CObjectInfo pub(elem.GetElement().GetPointedObject()); // the Pub field
4182  x_SetPubFieldInPub(pub);
4183  ++elem;
4184  }
4185 
4186  if (m_QualsChangedCount) {
4187  m_DataIter->SetModified();
4189  log << m_DataIter->GetBestDescr() << ": set new value to " << m_QualsChangedCount << " publication fields";
4190  x_LogFunction(log);
4191  }
4192 }
4193 
4195 {
4196  CPub* pub = static_cast<CPub*>(pub_oi.GetObjectPtr());
4197  if (!pub)
4198  return;
4199 
4200  CObjectInfo pub_var = pub_oi.GetCurrentChoiceVariant().GetVariant();
4201 
4202  switch (m_PubField) {
4203  case (ePubField_Date):
4204  return x_SetObjects_Date(*pub, pub_var);
4205  case ePubField_Affil:
4206  return x_SetObjects_Affil(*pub, pub_var);
4207  }
4208 }
4209 
4211 {
4212  if (m_PubField != ePubField_Date)
4213  return;
4214 
4215  switch (pub.Which()) {
4216  case (CPub::e_Gen):
4217  case (CPub::e_Sub): {
4218  CMQueryNodeValue::TObs res_oi;
4219  if (!SetFieldsByName(&res_oi, pub_var, "date.std")) {
4220  return;
4221  }
4222 
4223  _ASSERT(!res_oi.empty());
4224  if (res_oi.front().field.GetTypeFamily() != eTypeFamilyClass)
4225  return;
4226 
4227  CObjectInfoMI mem = res_oi.front().field.BeginMembers();
4228  auto it = m_Args.begin();
4229  for (; mem.Valid() && it != m_Args.end(); ++mem, ++it) {
4230  CObjectInfo tmp(res_oi.front().field.SetClassMember(mem.GetMemberIndex()));
4231  if (SetSimpleTypeValue(tmp, **it)) {
4233  }
4234  }
4235  }
4236  default:
4237  // not handling other type of publications for now
4238  break;
4239  }
4240 }
4241 
4243 {
4244  if (m_PubField != ePubField_Affil)
4245  return;
4246 
4247  switch (pub.Which()) {
4248  case (CPub::e_Gen):
4249  case (CPub::e_Sub): {
4250 
4251  string field_name("authors.affil.std.");
4252  field_name.append(m_Args[0]->GetString());
4253  CMQueryNodeValue::TObs res_oi;
4254  if (!SetFieldsByName(&res_oi, pub_var, field_name)) {
4255  return;
4256  }
4257 
4258  _ASSERT(!res_oi.empty());
4259  if (SetSimpleTypeValue(res_oi.front().field, *m_Args[1])) {
4261  }
4262  }
4263  default:
4264  // not handling other type of publications for now
4265  break;
4266  }
4267 }
4268 
4270 {
4271  vector<CMQueryNodeValue::EType> valid_types;
4272 
4273  switch (m_PubField) {
4274  case ePubField_Date: {
4275  if (m_Args.size() < 1 || m_Args.size() > 6)
4276  return false;
4277 
4278  for (size_t i = 0; i < m_Args.size(); ++i) {
4279  if (i == 3 && !m_Args[i]->IsString()) {
4280  return false;
4281  }
4282  else if (!m_Args[i]->IsInt()) {
4283  return false;
4284  }
4285  }
4286  break;
4287  }
4288  case ePubField_Affil:
4289  return (m_Args.size() == 2 && m_Args[0]->IsString() && m_Args[1]->IsString());
4290  }
4291 
4292  return true;
4293 }
4294 
4295 
4296 END_SCOPE(macro)
4298 
4299 /* @} */
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
Utility macros and typedefs for exploring NCBI objects from biblio.asn.
#define FOR_EACH_ARTICLEID_ON_CITART(Itr, Var)
#define EDIT_EACH_ARTICLEID_ON_CITART(Itr, Var)
#define ERASE_ARTICLEID_ON_CITART(Itr, Var)
@Affil.hpp User-defined methods of the data storage class.
Definition: Affil.hpp:56
CArticleId –.
Definition: ArticleId.hpp:66
@Auth_list.hpp User-defined methods of the data storage class.
Definition: Auth_list.hpp:57
size_t GetNameCount() const
Definition: Auth_list.cpp:58
CAuthor –.
Definition: Author.hpp:59
static CRef< CAuthor > ConvertMlToStandard(const CAuthor &author, bool normalize_suffix=false)
Definition: Author.cpp:269
CBioseq_CI –.
Definition: bioseq_ci.hpp:69
CBioseq_Handle –.
CBioseq_set_Handle –.
Definition: Date.hpp:53
void SetToTime(const CTime &time, EPrecision prec=ePrecision_second)
Definition: Date.cpp:57
@ ePrecision_day
Definition: Date.hpp:58
static pair< CRef< objects::CPubdesc >, string > GetPubFromCrossRef(const string &doi)
Definition: doi_lookup.cpp:806
void Fetch(const string &db, const vector< objects::CSeq_id_Handle > &uids, CNcbiOstream &ostr, const string &retmode="xml")
void SetMaxReturn(int ret_max)
static void s_DoLookup(const string &old_title, vector< string > &titles)
CImprint –.
Definition: Imprint.hpp:66
Subclass of the IQueryParseUserObject which is held as the user-defined object in each CQueryParseNod...
Definition: macro_exec.hpp:71
CMacroBioData_PubdescIter - iterates over all publication descriptors and features in the seq-entry.
@Name_std.hpp User-defined methods of the data storage class.
Definition: Name_std.hpp:56
CObjectInfoCV –.
Definition: objectiter.hpp:588
CObjectInfoEI –.
Definition: objectiter.hpp:125
CObjectInfoMI –.
Definition: objectiter.hpp:432
CObjectInfo –.
Definition: objectinfo.hpp:597
static EPubFieldStatus GetStatusFromString(const string &str)
static bool SetImprint(objects::CPub &pub, const objects::CImprint &imp)
static string GetLabelForStatus(EPubFieldStatus status)
static CConstRef< objects::CImprint > GetImprint(const objects::CPub &pub)
Definition: Pub.hpp:56
CAuth_list & SetAuthors(void)
Definition: Pub.cpp:204
bool IsSetAuthors(void) const
Definition: Pub.cpp:152
@Pubdesc.hpp User-defined methods of the data storage class.
Definition: Pubdesc.hpp:54
CPubmed_entry –.
CSeq_entry_Handle –.
Definition: Seq_entry.hpp:56
CSeqdesc_CI –.
Definition: seqdesc_ci.hpp:65
class CStaticArrayMap<> provides access to a static array in much the same way as CStaticArraySet<>,...
Definition: static_map.hpp:175
TBase::const_iterator const_iterator
Definition: static_map.hpp:179
static string FixDateFormat(const string &orig_date)
Attempt to fix the format of the date Returns a blank if the format of the date cannot be determined.
Definition: SubSource.cpp:620
static CRef< CDate > DateFromCollectionDate(const string &str) THROWS((CException))
Definition: SubSource.cpp:287
static void DetectDateFormat(const string &orig_date, bool &ambiguous, bool &day_first)
Definition: SubSource.cpp:1176
CSubmit_block –.
C_E –.
Definition: Title_.hpp:96
Definition: Title.hpp:51
const string & GetTitle(C_E::E_Choice type=C_E::e_not_set) const
If the internal list contains a title (of the specified type, if given), returns the corresponding st...
Definition: Title.cpp:56
static bool GetBestId(CSeq_id_Handle, CScope &, string &)
Definition: write_util.cpp:675
Base class for any user function that performs editing operations on ASN.1 data.
const_iterator end() const
Definition: map.hpp:152
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: set.hpp:45
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
EPubmedError
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static const struct name_t names[]
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
static char tmp[3200]
Definition: utf8.c:42
SStrictId_Entrez::TId TEntrezId
TEntrezId type for entrez ids which require the same strictness as TGi.
Definition: ncbimisc.hpp:1041
#define ENTREZ_ID_TO(T, entrez_id)
Definition: ncbimisc.hpp:1097
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
Int8 TIntId
Definition: ncbimisc.hpp:999
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define ENTREZ_ID_FROM(T, value)
Definition: ncbimisc.hpp:1098
#define ZERO_ENTREZ_ID
Definition: ncbimisc.hpp:1102
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
static void s_GetObjectsFromAuthListNames(const CObjectInfo &names, const string &field_name, CMQueryNodeValue::TObs &objs)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
void x_GetObjectsForPubField_SerialNumber(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
void x_GetObjectsForPubField_Title(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
static string s_GetFirstNameInitials(const string &first_name)
void x_GetObjectsForPubField_VolIssuePage(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
bool ApplyMiddleInitial(objects::CName_std &std_name, const string &newValue, objects::edit::EExistingText existing_text)
static string s_InsertInitialPeriods(const string &orig)
bool SetQualStringValue(CObjectInfo &oi, const string &value)
Functions make the action and collect statistics.
void SetString(const string &data)
Set/get underlying data type.
Definition: macro_exec.hpp:125
static const char * sm_PubIssue
void x_SetPubFieldInPub(CObjectInfo &pub_oi)
static bool s_FixInitials(objects::CName_std &name)
string m_ResField
used for resolving fields for authors, date, affiliation
string x_GetPubStatus(const CObjectInfo &pubdesc_oi)
void x_RemoveVolIssuePagesInPubdesc(objects::CPubdesc &pubdesc)
static bool s_SetStatus(objects::CPubdesc &pubdesc, const string &value)
ENestedFunc m_Nested
flag indicating whether the function is nested within another function
static const TAuthorFixPair s_AuthorFixString[]
static const char * sm_FunctionName
class CMacroFunction_SetPubField SetPub_Date(year, month, day, season, hour, minute,...
virtual void TheFunction()
Function implementation.
static void s_GetObjectsFromTitle(const CObjectInfo &title, CMQueryNodeValue::TObs &objs)
static bool s_IsPubFieldFnc(const string &fn_name)
void x_LogChangedQuals(const CRef< IFunctionLog > &log)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
static const char * sm_FunctionName
class CMacroFunction_ApplyPublication SetPub_Sub(author_field_name, author_field_value) Apply new pub...
void x_GetObjectsForPubField_Cit(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
static const char * sm_PubJournal
CStaticArrayMap< string, CMacroFunction_AuthorFix::EActionType > TAuthorFixTypeMap
CMQueryNodeValue::EType GetPrimitiveFromRef(CMQueryNodeValue &node)
Definition: macro_util.cpp:274
virtual void TheFunction()
Function implementation.
void x_RemoveDateField(CMQueryNodeValue::TObs &objs)
static void s_GetObjectsFromImprint(const CObjectInfo &imp, const string &field_name, CMQueryNodeValue::TObs &objs)
DEFINE_STATIC_ARRAY_MAP(TAuthorFixTypeMap, sm_AuthorFixMap, s_AuthorFixString)
bool ResolveAndSetSimpleTypeValue(CObjectInfo &oi, const string &field_name, const CMQueryNodeValue &value, objects::edit::EExistingText existing_text=objects::edit::eExistingText_replace_old)
Resolve dot qualified ASN.1 node_name using the object information instance provided as a parameter (...
bool RemoveFieldByName(CMQueryNodeValue::SResolvedField &res_field)
Remove the object information instance corresponding to field, using information about its parent nod...
list< SResolvedField > TObs
Definition: macro_exec.hpp:92
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
map< string, vector< string > > m_Hits
void x_GetObjectsForPubField_Date(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
static void s_GetObjectsFromAffil(const CObjectInfo &affil, const string &field_name, CMQueryNodeValue::TObs &objs)
static const char * sm_PubSerialNumber
void AssignFromObjectInfo(const CObjectInfo &objinfo)
Assigns data from objinfo. It is used when storing evaluation result.
Definition: macro_exec.cpp:111
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
static const char * sm_FuncVolume
class CMacroFunction_SetPubVolIssuePages SetPubVolume(newValue, existing_text, delimiter,...
void x_SetAuthorInPubdesc(objects::CPubdesc &pubdesc, const string &field, const CMQueryNodeValue &value, objects::edit::EExistingText existing_text)
static const char * sm_PubAuthors
static void s_CopyResolvedObjs(const CMQueryNodeValue::TObs &objs_from, CMQueryNodeValue::TObs &objs_to)
bool SetSimpleTypeValue(CObjectInfo &oi, const CMQueryNodeValue &value, objects::edit::EExistingText existing_text=objects::edit::eExistingText_replace_old)
Set single node data to the node specified by parameter of type CObjectInfo.
void x_GetPubFieldObjectFromPub(const CObjectInfo &pub_oi, CMQueryNodeValue::TObs &objs)
string GetStringValue(CRef< CMQueryNodeValue > &value)
converts ints and doubles into string, by changing the type of the value
Definition: macro_util.cpp:330
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
unsigned ApplyAuthorNames(objects::CAuth_list &auth_list, const string &newValue)
void x_SetObjects_Date(objects::CPub &pub, CObjectInfo &pub_var)
void x_GetObjectsForPubField_Authors(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
void x_SetTitleInPubdesc(objects::CPubdesc &pubdesc, const string &value)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
virtual void TheFunction()
Function implementation.
CMacroFunction_PubFields(EScopeEnum func_scope, objects::EPublication_field field)
CObjectInfo GetPrimitiveObjInfo(const CObjectInfo &info)
Definition: macro_util.cpp:199
virtual void TheFunction()
Function implementation.
void x_LookupTitleInJournal(objects::CCit_jour &journal)
static const string & GetDescription(EActionType fix_type)
vector< string > x_FindIsoJtaTitle(const string &title)
static void s_GetObjectsFromDate(const CObjectInfo &date, const string &field_name, CMQueryNodeValue::TObs &objs)
static set< string > s_GatherExistingDOIs(const CBioseq_Handle &bsh)
virtual void TheFunction()
Function implementation.
static bool s_ReverseAuthorNames(objects::CName_std &name)
bool x_HasIsoJtaTitle(const objects::CTitle &title) const
void x_GetOptionalArgs(string &delimiter, bool &remove_field, size_t &index)
void x_SetTitleInSubmitBlock(objects::CSubmit_block &submit_block, const string &value)
static string x_GetStatus(const objects::CPub &pub)
void x_GetObjectsForPubField_AffilField(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
Int4 m_QualsChangedCount
Number of changed qualifiers during the function call.
bool GetFieldsByName(CMQueryNodeValue::TObs *results, const CObjectInfo &oi_i, const string &field_name)
Resolve existing dot qualified ASN.1 name (field_name) starting from the object information instance ...
static const char * sm_PubVolume
bool RemoveMiddleInitial(objects::CName_std &std_name)
void x_AddAuthorInPubdesc(objects::CPubdesc &pubdesc, objects::edit::EExistingText existing_text)
void SetRef(CRef< CMQueryNodeValue > node)
Definition: macro_exec.hpp:130
void x_SetAffilField(objects::CAuth_list &auth_list, const string &field, const string &value, objects::edit::EExistingText existing_text)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
objects::EPublication_field m_FieldType
virtual void TheFunction()
Function implementation.
DEFINE_MACRO_FUNCNAME(CMacroFunction_MoveMiddleName, "MoveMiddleToFirstName")
class CMacroFunction_AuthorFix MoveMiddleToFirstName(); - moves middle name to first name and fixes t...
bool SetFieldsByName(CMQueryNodeValue::TObs *results, CObjectInfo &oi_i, const string &field_name)
Resolve not necessarily existing dot qualified ASN.1 name (field_name) starting from the object infor...
void x_RemoveAffilField(objects::CAuth_list &auth_list, const string &field)
static const char * sm_PubStatus
void x_RemoveJournalInPubdesc(objects::CPubdesc &pubdesc)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
objects::edit::EExistingText ActionTypeToExistingTextOption(const string &action_type, const string &delimiter)
Definition: macro_util.cpp:64
static const char * sm_PubTitle
class CMacroFunction_PubFields PUB_TITLE(), PUB_ISSUE(), PUB_AFFIL(subfield) - returns a list of CObj...
static void s_BuildName(const string &firstname, const string &mid_initials, const string &lastname, const string &suffix, objects::CName_std &name)
void x_GetObjectsForPubField_PMID(objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
const string & x_GetIsoJtaTitle(const objects::CTitle &title) const
static bool s_TruncateMiddleInitials(objects::CName_std &name)
vector< pair< string, string > > m_TitlePairs
int x_MakeAuthorChanges(objects::CAuth_list &auth_list)
CRef< CMQueryNodeValue > m_Result
static bool s_IsUnpublished(const string &citation)
static Int4 s_RemoveFields(CIRef< IMacroBioDataIter > &dataiter, CMQueryNodeValue::TObs &objs)
static string s_GetFirstNameInitialsWithoutStops(const string &first_name)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
void x_AddDate(CMQueryNodeValue::TObs &objs)
void x_SetNewAuthor(objects::CAuth_list &auth_list, const string &field, const CMQueryNodeValue &value)
void SetStrings(const vector< string > &data)
Definition: macro_exec.hpp:126
void x_GetPubFieldObjectFromSubmitBlock(const CObjectInfo &block_oi, CMQueryNodeValue::TObs &objs)
static const char * sm_PubPMID
static set< TEntrezId > s_GatherExistingPMIDs(const CBioseq_Handle &bsh)
static const char * sm_PubDate
static const char * sm_PubAffil
void x_AddDateField(CMQueryNodeValue::TObs &objs)
void x_AddAuthorListInPubdesc(objects::CPubdesc &pubdesc)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
static const char * sm_PubCit
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
void x_LogFunction(CNcbiOstrstream &logstr)
static void s_GetObjectsFromPersonID(const CObjectInfo &names, const string &field_name, CMQueryNodeValue::TObs &objs)
bool ApplyFirstName(objects::CName_std &std_name, const string &newValue, objects::edit::EExistingText existing_text)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
void x_SetJournalInPubdesc(objects::CPubdesc &pubdesc, const string &value, objects::edit::EExistingText existing_text)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
void x_SetObjects_Affil(objects::CPub &pub, CObjectInfo &pub_var)
static CMQueryNodeValue::TObs s_GetPubVolIssuePagesDateObjects(CPubdesc &pubdesc, const string &field)
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
static string s_GetStatus(const objects::CPubdesc &pubdesc)
void SetObjects(const TObs &obs)
Definition: macro_exec.hpp:131
static const char * sm_PubPages
static CRef< objects::CPub > s_GetArticleFromEntrezById(TEntrezId pmid, bool asn_format=false)
static CRef< CSeqdesc > s_MakeNewPubdesc(CRef< CPub > &new_pub, TEntrezId pmid)
static EActionType GetActionType(const string &descr)
void x_GetObjectsForPubField_Journal(const objects::CPub &pub, const CObjectInfo &pub_var, CMQueryNodeValue::TObs &objs)
void x_AddAuthor(objects::CAuth_list &auth_list, objects::edit::EExistingText existing_text)
static bool s_MoveMiddleToFirst(objects::CName_std &name)
static CObjectInfo s_GetRelevantObjectInfoForPub(const CPub &pub, const CObjectInfo &pub_var)
CIRef< IMacroBioDataIter > m_DataIter
SStaticPair< const char *, CMacroFunction_AuthorFix::EActionType > TAuthorFixPair
static CPubFieldType::EPubFieldStatus s_GetStatusEnum(const objects::CPub &pub)
void x_SetVolIssuePagesInPubdesc(objects::CPubdesc &pubdesc, const string &value, objects::edit::EExistingText existing_text)
static const char * sm_PubClass
virtual void TheFunction()
Function implementation.
static bool x_SetStatus(objects::CPub &pub, CPubFieldType::EPubFieldStatus status)
TPrim & Set(void)
Definition: serialbase.hpp:351
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
virtual const CTypeInfo * GetThisTypeInfo(void) const =0
static const TObjectType * SafeCast(TTypeInfo type)
Definition: serialutil.hpp:76
#define MSerial_AsnText
I/O stream manipulators –.
Definition: serialbase.hpp:696
virtual bool Equals(const CSerialObject &object, ESerialRecursionMode how=eRecursive) const
Check if both objects contain the same values.
@ ePrimitiveValueString
string|char*|const char*
Definition: serialdef.hpp:153
@ ePrimitiveValueInteger
(signed|unsigned) (char|short|int|long)
Definition: serialdef.hpp:151
@ eTypeFamilyClass
Definition: serialdef.hpp:140
@ eTypeFamilyContainer
Definition: serialdef.hpp:142
@ eTypeFamilyPointer
Definition: serialdef.hpp:143
@ eTypeFamilyPrimitive
Definition: serialdef.hpp:139
bool Valid(void) const
Is iterator valid.
CElementIterator BeginElements(void) const
Create container elements iterator.
TMemberIndex GetMemberIndex(void) const
Get index of the member in the class.
pair< TObjectPtr, TTypeInfo > ObjectInfo(C &obj)
Definition: objectinfo.hpp:762
CObjectInfo GetPointedObject(void) const
Get data and type information of object to which this type refers.
Definition: objectinfo.cpp:102
CObjectInfo GetElement(void) const
Get element data and type information.
CMemberIterator BeginMembers(void) const
Create class member iterator.
TObjectPtr GetObjectPtr(void) const
Get pointer to object.
CObjectInfo GetMember(void) const
Get class member data.
TMemberIndex GetCurrentChoiceVariantIndex(void) const
Get index of currently selected choice variant.
Definition: objectinfo.cpp:302
CChoiceVariant GetCurrentChoiceVariant(void) const
Get data and type information of selected choice variant.
int GetPrimitiveValueInt(void) const
Get data as int.
Definition: objectinfo.cpp:154
CObjectInfo GetVariant(void) const
Get variant data.
bool Valid(void) const
Is iterator valid.
ETypeFamily GetTypeFamily(void) const
Get data type family.
void GetPrimitiveValueString(string &value) const
Get string data.
Definition: objectinfo.cpp:199
CMemberIterator FindClassMember(const string &memberName) const
Find class member by its name.
const string & GetName(void) const
Get type name.
Definition: objectinfo.hpp:106
void SetPrimitiveValueInt(int value)
Definition: objectinfo.cpp:257
EPrimitiveValueType GetPrimitiveValueType(void) const
Get type of primitive value.
Definition: objectinfo.cpp:109
bool IsSet(void) const
Is member assigned a value.
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
TClass GetClass(void) const
CBioseq_set_Handle GetParentBioseq_set(void) const
Return a handle for the parent Bioseq-set, or null handle.
CSeq_id_Handle GetAccessSeq_id_Handle(void) const
Get any CSeq_id_Handle handle that can be used to access this bioseq Use GetSeq_id_Handle() if it's n...
CSeq_entry_Handle GetSeq_entry_Handle(void) const
Get parent Seq-entry handle.
CBioseq_set_Handle GetParentBioseq_set(void) const
Return a handle for the parent Bioseq-set, or null handle.
CSeq_entry_Handle GetParentEntry(void) const
Return a handle for the parent seq-entry of the bioseq.
bool IsSetClass(void) const
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define USING_SCOPE(ns)
Use the specified namespace.
Definition: ncbistl.hpp:78
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
static string Int8ToString(Int8 value, TNumToStringFlags flags=0, int base=10)
Convert Int8 to string.
Definition: ncbistr.hpp:5159
#define kEmptyStr
Definition: ncbistr.hpp:123
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static Int8 StringToInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Int8.
Definition: ncbistr.cpp:793
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3201
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static bool EqualCase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-sensitive equality of a substring with another string.
Definition: ncbistr.hpp:5325
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3405
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
@ eCase
Case sensitive compare.
Definition: ncbistr.hpp:1205
CTime CurrentTime(CTime::ETimeZone tz=CTime::eLocal, CTime::ETimeZonePrecision tzp=CTime::eTZPrecisionDefault)
Definition: ncbitime.hpp:2185
bool IsProc(void) const
Check if variant Proc is selected.
Definition: Cit_art_.hpp:507
void SetBook(TBook &value)
Assign a value to Book data member.
Definition: Cit_proc_.cpp:61
const TBook & GetBook(void) const
Get the Book member data.
Definition: Cit_proc_.hpp:214
bool IsSetAuthors(void) const
Check if a value has been assigned to Authors data member.
Definition: Cit_gen_.hpp:623
bool IsSetAuthors(void) const
authors (ANSI requires) Check if a value has been assigned to Authors data member.
Definition: Cit_art_.hpp:534
const TJournal & GetJournal(void) const
Get the variant data.
Definition: Cit_art_.cpp:111
void SetAuthors(TAuthors &value)
Assign a value to Authors data member.
Definition: Cit_pat_.cpp:68
const TFrom & GetFrom(void) const
Get the From member data.
Definition: Cit_art_.hpp:567
const TCit & GetCit(void) const
Get the Cit member data.
Definition: Cit_gen_.hpp:588
void ResetNames(void)
Reset Names data member.
Definition: Auth_list_.cpp:139
void SetName(TName &value)
Assign a value to Name data member.
Definition: Author_.cpp:81
void SetAffil(TAffil &value)
Assign a value to Affil data member.
Definition: Auth_list_.cpp:160
bool IsSetFrom(void) const
Check if a value has been assigned to From data member.
Definition: Cit_art_.hpp:555
void SetAuthors(TAuthors &value)
Assign a value to Authors data member.
Definition: Cit_art_.cpp:227
bool IsSetAuthors(void) const
not necessarily authors of the paper Check if a value has been assigned to Authors data member.
Definition: Cit_sub_.hpp:345
const TName & GetName(void) const
Get the Name member data.
Definition: Author_.hpp:352
void SetAuthors(TAuthors &value)
Assign a value to Authors data member.
Definition: Cit_sub_.cpp:74
void ResetPrepub(void)
Reset Prepub data member.
Definition: Imprint_.hpp:1092
bool IsSetCit(void) const
anything, not parsable Check if a value has been assigned to Cit data member.
Definition: Cit_gen_.hpp:576
const TProc & GetProc(void) const
Get the variant data.
Definition: Cit_art_.cpp:155
list< CRef< CAuthor > > TStd
Definition: Auth_list_.hpp:170
void SetCit(TCit &value)
Assign a value to Cit data member.
Definition: Cit_let_.cpp:70
void ResetCit(void)
Reset Cit data member.
Definition: Cit_gen_.cpp:53
bool IsSetNames(void) const
Check if a value has been assigned to Names data member.
Definition: Auth_list_.hpp:464
void SetCit(const TCit &value)
Assign a value to Cit data member.
Definition: Cit_gen_.hpp:597
void SetNames(TNames &value)
Assign a value to Names data member.
Definition: Auth_list_.cpp:149
void SetAuthors(TAuthors &value)
Assign a value to Authors data member.
Definition: Cit_book_.cpp:93
bool IsSetName(void) const
Author, Primary or Secondary Check if a value has been assigned to Name data member.
Definition: Author_.hpp:340
bool IsSet(void) const
Check if a value has been assigned to data member.
Definition: Title_.hpp:769
bool IsBook(void) const
Check if variant Book is selected.
Definition: Cit_art_.hpp:501
bool IsJournal(void) const
Check if variant Journal is selected.
Definition: Cit_art_.hpp:495
const TNames & GetNames(void) const
Get the Names member data.
Definition: Auth_list_.hpp:478
bool IsMl(void) const
Check if variant Ml is selected.
Definition: Auth_list_.hpp:424
const TStd & GetStd(void) const
Get the variant data.
Definition: Auth_list_.hpp:410
void SetPrepub(TPrepub value)
Assign a value to Prepub data member.
Definition: Imprint_.hpp:1108
const TMl & GetMl(void) const
Get the variant data.
Definition: Auth_list_.hpp:430
const Tdata & Get(void) const
Get the member data.
Definition: Title_.hpp:781
void SetAuthors(TAuthors &value)
Assign a value to Authors data member.
Definition: Cit_gen_.cpp:64
Tdata & Set(void)
Assign a value to data member.
Definition: Title_.hpp:787
bool IsStd(void) const
Check if variant Std is selected.
Definition: Auth_list_.hpp:404
const TBook & GetBook(void) const
Get the variant data.
Definition: Cit_art_.cpp:133
@ e_not_set
No variant selected.
Definition: Title_.hpp:110
@ ePrepub_in_press
accepted, not published
Definition: Imprint_.hpp:96
void SetYear(TYear value)
Assign a value to Year data member.
Definition: Date_std_.hpp:435
void ResetLast(void)
Reset Last data member.
Definition: Name_std_.cpp:50
void SetInitials(const TInitials &value)
Assign a value to Initials data member.
Definition: Name_std_.hpp:619
bool IsSetSuffix(void) const
Jr, Sr, III Check if a value has been assigned to Suffix data member.
Definition: Name_std_.hpp:645
void ResetInitials(void)
Reset Initials data member.
Definition: Name_std_.cpp:74
const TInitials & GetInitials(void) const
Get the Initials member data.
Definition: Name_std_.hpp:610
void ResetFirst(void)
Reset First data member.
Definition: Name_std_.cpp:56
bool IsName(void) const
Check if variant Name is selected.
Definition: Person_id_.hpp:359
void SetLast(const TLast &value)
Assign a value to Last data member.
Definition: Name_std_.hpp:431
void SetFirst(const TFirst &value)
Assign a value to First data member.
Definition: Name_std_.hpp:478
bool IsSetInitials(void) const
first + middle initials Check if a value has been assigned to Initials data member.
Definition: Name_std_.hpp:598
TConsortium & SetConsortium(void)
Select the variant.
Definition: Person_id_.hpp:418
bool IsSetLast(void) const
Check if a value has been assigned to Last data member.
Definition: Name_std_.hpp:410
void SetSuffix(const TSuffix &value)
Assign a value to Suffix data member.
Definition: Name_std_.hpp:666
TName & SetName(void)
Select the variant.
Definition: Person_id_.cpp:143
TYear GetYear(void) const
Get the Year member data.
Definition: Date_std_.hpp:426
const TFirst & GetFirst(void) const
Get the First member data.
Definition: Name_std_.hpp:469
const TLast & GetLast(void) const
Get the Last member data.
Definition: Name_std_.hpp:422
bool IsSetFirst(void) const
Check if a value has been assigned to First data member.
Definition: Name_std_.hpp:457
const TStd & GetStd(void) const
Get the variant data.
Definition: Date_.cpp:109
void ResetSuffix(void)
Reset Suffix data member.
Definition: Name_std_.cpp:80
EPublication_field
publication fields
@ ePublication_field_affiliation
@ ePublication_field_cit
@ ePublication_field_pages
@ ePublication_field_pmid
@ ePublication_field_pub_class
@ ePublication_field_issue
@ ePublication_field_date
@ ePublication_field_title
@ ePublication_field_serial_number
@ ePublication_field_authors
@ ePublication_field_volume
@ ePublication_field_journal
bool IsPmid(void) const
Check if variant Pmid is selected.
Definition: Pub_.hpp:677
TProc & SetProc(void)
Select the variant.
Definition: Pub_.cpp:305
TPmid & SetPmid(void)
Select the variant.
Definition: Pub_.hpp:690
TBook & SetBook(void)
Select the variant.
Definition: Pub_.cpp:283
const TArticle & GetArticle(void) const
Get the variant data.
Definition: Pub_.cpp:233
bool IsSet(void) const
Check if a value has been assigned to data member.
Definition: Pub_equiv_.hpp:153
const Tdata & Get(void) const
Get the member data.
Definition: Pub_equiv_.hpp:165
void Select(E_Choice index, EResetVariant reset=eDoResetVariant)
Select the requested variant if needed.
E_Choice Which(void) const
Which variant is currently selected.
Definition: Pub_.hpp:555
TMan & SetMan(void)
Select the variant.
Definition: Pub_.cpp:371
TSub & SetSub(void)
Select the variant.
Definition: Pub_.cpp:195
bool IsSub(void) const
Check if variant Sub is selected.
Definition: Pub_.hpp:590
virtual void Reset(void)
Reset the whole object.
Definition: Pub_.cpp:61
TGen & SetGen(void)
Select the variant.
Definition: Pub_.cpp:173
const TGen & GetGen(void) const
Get the variant data.
Definition: Pub_.cpp:167
TPatent & SetPatent(void)
Select the variant.
Definition: Pub_.cpp:327
bool IsArticle(void) const
Check if variant Article is selected.
Definition: Pub_.hpp:629
TArticle & SetArticle(void)
Select the variant.
Definition: Pub_.cpp:239
bool IsGen(void) const
Check if variant Gen is selected.
Definition: Pub_.hpp:584
bool IsMan(void) const
Check if variant Man is selected.
Definition: Pub_.hpp:665
@ e_Pmid
PubMedId.
Definition: Pub_.hpp:114
@ e_Article
Definition: Pub_.hpp:106
@ e_Pat_id
identify a patent
Definition: Pub_.hpp:111
@ e_Book
Definition: Pub_.hpp:108
@ e_Medline
Definition: Pub_.hpp:104
@ e_Gen
general or generic unparsed
Definition: Pub_.hpp:102
@ e_Journal
Definition: Pub_.hpp:107
@ e_Patent
Definition: Pub_.hpp:110