1 
2 /******************************************************************************
3 * MODULE     : metadata-elsevier.cpp
4 * DESCRIPTION: conversion of (Elsevier) TeX metadata into TeXmacs metadata
5 * COPYRIGHT  : (C) 2012 Joris van der Hoeven, Poulain François
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11 
12 #include "convert.hpp"
13 #include "metadata.hpp"
14 
15 static bool
is_elsevier_note_ref(tree t)16 is_elsevier_note_ref (tree t) {
17   return is_tuple (t, "\\tnoteref")  || is_tuple (t, "\\fnref") ||
18          is_tuple (t, "\\thanksref");
19 }
20 
21 #define cenr clean_elsevier_notes_refs
22 
23 static tree
clean_elsevier_notes_refs(tree t)24 clean_elsevier_notes_refs (tree t) {
25   if (is_atomic (t)) return t;
26   tree r (L(t));
27   int i, n=N(t);
28   for (i=0; i<n; i++) {
29     if (!is_elsevier_note_ref (t[i]))
30       r << clean_elsevier_notes_refs (t[i]);
31   }
32   return r;
33 }
34 
35 static array<tree>
find_all_tuples(tree t,string s)36 find_all_tuples (tree t, string s) {
37   array<tree> r;
38   if (is_atomic (t)) return r;
39   int i, n=N(t);
40   for (i=0; i<n; i++) {
41     if (is_tuple (t[i], s)) r << t[i];
42     else r << find_all_tuples (t[i], s);
43   }
44   return r;
45 }
46 
47 static array<string>
get_elsevier_author_refs(tree u)48 get_elsevier_author_refs (tree u) {
49   array<string> r;
50   array<tree> t;
51   if (is_tuple (u, "\\author*", 2))
52     r << tokenize (string_arg (u[1]), ",");
53   u= u[N(u)-1];
54   t = find_all_tuples (u, "\\thanksref");
55   for (int i=0; i<N(t); i++) r << string_arg (t[i][1]);
56   t = find_all_tuples (u, "\\fnref");
57   for (int i=0; i<N(t); i++) r << tokenize (string_arg (t[i][1]), ",");
58   return r;
59 }
60 
61 static array<tree>
get_elsevier_author_attributes(tree t,array<string> refs)62 get_elsevier_author_attributes (tree t, array<string> refs) {
63   int i, n=N(t);
64   array<tree> r;
65   for (i=0; i<n; i++)
66     if (is_tuple (t[i]) && !is_tuple (t[i], "\\author*") && N(t[i]) > 1 &&
67         ends (as_string (t[i][0]), "*") &&
68         contains (string_arg (t[i][1]), refs))
69        r << t[i];
70   return r;
71 }
72 
73 static tree
translate_author_metadata_elsevier(tree u)74 translate_author_metadata_elsevier (tree u) {
75   if (!is_tuple (u) || N(u)<2)
76     return concat ();
77   if (is_tuple (u, "\\address*", 2))
78     return tree (APPLY, "\\author-affiliation", cenr (u[2]));
79   if (is_tuple (u, "\\thanks*", 2) || is_tuple (u, "\\fntext*", 2))
80     return tree (APPLY, "\\author-note", cenr (u[2]));
81   if (is_tuple (u, "\\thanksamisc*", 2) || is_tuple (u, "\\fmtext*", 2))
82     return tree (APPLY, "\\author-misc", cenr (u[2]));
83   if (is_tuple (u, "\\thanksemail*", 2))
84     return tree (APPLY, "\\author-email", cenr (u[2]));
85   if (is_tuple (u, "\\thankshomepage*", 2))
86     return tree (APPLY, "\\author-homepage", cenr (u[2]));
87   return concat ();
88 }
89 
90 static array<tree>
translate_abstract_data_elsevier(tree t)91 translate_abstract_data_elsevier (tree t) {
92   array<tree> r;
93   int i=0, n=N(t);
94   tree comp (APPLY, "\\abstract-keywords");
95   tree word (CONCAT);
96   for (i=0; i<n; i++) {
97     if (is_tuple (t[i], "\\PACS")) {
98       comp << word;
99       if (N(comp) > 1) r << comp;
100       word= concat ();
101       comp= tree (APPLY, "\\abstract-pacs");
102     }
103     else if (is_tuple (t[i], "\\MSC")) {
104       comp << word;
105       if (N(comp) > 1) r << comp;
106       word= concat ();
107       comp= tree (APPLY, "\\abstract-msc");
108     }
109     else if (is_tuple (t[i], "\\tmacm") || is_tuple (t[i], "\\tmarxiv"))
110           r << collect_abstract_data (t[i]);
111     else if (is_tuple (t[i], "\\sep")) {
112       comp << word;
113       word= concat ();
114     }
115     else
116       word << t[i];
117   }
118   if (N(word) > 1) comp << word;
119   if (N(comp) > 1) r << comp;
120   return r;
121 }
122 
123 static tree
translate_metadata_elsevier(tree t)124 translate_metadata_elsevier (tree t) {
125   int i, n=N(t);
126   bool clustered= false;
127   tree u, r (CONCAT);
128   tree doc_data (APPLY, "\\doc-data");
129   tree abstract (APPLY, "\\abstract-data");
130   tree author (APPLY, "\\author-data");
131   array<string> authors_stuff;
132   for (i=0; i<n; i++) {
133     u= t[i];
134     if (is_tuple (u, "\\title", 1))
135       doc_data << tree (APPLY, "\\doc-title", cenr (u[1]));
136     else if (is_tuple (u, "\\thankssubtitle*", 2) ||
137              is_tuple (u, "\\tsubtitletext*", 2))
138       doc_data << tree (APPLY, "\\doc-subtitle", cenr (u[2]));
139     else if (is_tuple (u, "\\thanksmisc*", 2) ||
140              is_tuple (u, "\\tmisctext*", 2))
141       doc_data << tree (APPLY, "\\doc-misc", cenr (u[2]));
142     else if (is_tuple (u, "\\thanksdate*", 2) ||
143              is_tuple (u, "\\tdatetext*", 2))
144       doc_data << tree (APPLY, "\\doc-date", cenr (u[2]));
145     else if (is_tuple (u, "\\thanks*", 2)
146         && !contains (string_arg (u[1]), authors_stuff))
147       doc_data << tree (APPLY, "\\doc-note", cenr (u[2]));
148     else if (is_tuple (u, "\\tnotetext*", 2))
149       doc_data << tree (APPLY, "\\doc-note", cenr (u[2]));
150     else if (is_tuple (u, "\\author*", 2) || is_tuple (u, "\\author", 1)) {
151       if (N(author) > 1) doc_data << tree (APPLY, "\\doc-author", author);
152       if (is_tuple (u, "\\author*", 2)) clustered= true;
153       array<string> refs= get_elsevier_author_refs (u);
154       array<tree> attrs= get_elsevier_author_attributes (t, refs);
155       author= tree (APPLY, "\\author-data",
156                     tree (APPLY, "\\author-name", cenr (u[N(u)-1])));
157       authors_stuff << refs;
158       for (int j=0; j<N(attrs); j++)
159         author << translate_author_metadata_elsevier (attrs[j]);
160     }
161     else if (is_tuple (u, "\\address", 1))
162         author << tree (APPLY, "\\author-affiliation", cenr (u[1]));
163     else if (is_tuple (u, "\\ead", 1))
164         author << tree (APPLY, "\\author-email", cenr (u[1]));
165     else if (is_tuple (u, "\\ead*", 2) && string_arg (u[1]) == "url")
166         author << tree (APPLY, "\\author-homepage", cenr (u[2]));
167     else if (is_tuple (u, "\\begin-abstract")) {
168       tree abstract_text (CONCAT);
169       i++;
170       while (i<n && !is_tuple (t[i], "\\end-abstract"))
171         abstract_text << t[i++];
172       abstract << tree (APPLY, "\\abstract", abstract_text);
173     }
174     else if (is_tuple (u, "\\begin-keyword")) {
175       tree keywords (CONCAT);
176       i++;
177       while (i<n && !is_tuple (t[i], "\\end-keyword"))
178         keywords << t[i++];
179       array<tree> abstract_data= translate_abstract_data_elsevier (keywords);
180       for (int j=0; j<N(abstract_data); j++)
181         abstract << abstract_data[j];
182     }
183   }
184   if (N(author) > 1) doc_data << tree (APPLY, "\\doc-author", author);
185   if (clustered) doc_data << tree (APPLY, "\\doc-title-options", "cluster-all");
186   if (N(doc_data) > 1) r << doc_data << "\n";
187   if (N(abstract) > 1) r << abstract << "\n";
188   return r;
189 }
190 
191 tree
collect_metadata_elsevier(tree t)192 collect_metadata_elsevier (tree t) {
193   tree r (CONCAT);
194   if (is_atomic (t)) return r;
195   else {
196     int i, n=N(t);
197     for (i=0; i<n; i++) {
198       if (is_tuple (t[i], "\\begin-frontmatter")) {
199         r = concat ();
200         for (i++; i<n && !is_tuple (t[i], "\\end-frontmatter"); i++)
201           r << t[i];
202         return translate_metadata_elsevier (r);
203       }
204       else {
205         r= collect_metadata_elsevier (t[i]);
206         if (N(r) > 0) return r;
207       }
208     }
209     return r;
210   }
211 }
212 
213 #undef cenr
214