3
$\begingroup$

Say I have a string like this

article{a2,
  author  = {F1name L1name, F2name M2name L2name}, 
  title   = {The title of the work},
  journal = {The Journal2},
  year    = 1994,
  number  = 3,
  pages   = {204-223},
  month   = 6,
  note    = {An optional note}, 
  volume  = 2
}

This is how the input looks like in notebook.

"article{a2,\n author = {F1name L1name, F2name M2name L2name}, \n title \ = {The title of the work},\n journal = {The Journal2},\n year = 1994,\n \ number = 3,\n pages = {204-223},\n month = 6,\n note = {An \ optional note}, \n volume = 2\n}"

How can I store these data a variable entry like this

entry["a2"]={"a2", "article", "F1name L1name, F2name M2name L2name",
             "The title of the work","The Journal2","2","204-223","1994"}

I have to maintain the order

entry [ key] = {key, type, author, title, journal, volume, pages, year}


Why I am doing this !

As you probably recognise that I am trying to create bibliographic items from a .bib file (check this Wikipedia entry on BibTex for more details). Above is an entry you get when you run

StringSplit[Import["a.bib"], "@"][[2]]

Then I define a style

shortname[name_] := Module[{nparts},
 nparts = StringSplit[name];
 StringJoin[ ToString[StringForm["``. ", StringTake[#, 1]]] & /@ 
 nparts[[1 ;; -2]], ToString[nparts[[-1]]]]]

authornames[authors_] := Module[{n, names},
 names = shortname[#] & /@ Flatten[StringSplit[authors, ","]];
 n = Length[names];
 If[n > 1, StringJoin[ToString@StringForm["``, ", #] & /@ names[[1 ;; -2]], 
"and ", ToString[names[[-1]]]], names]]

abbvr["The Journal2"] = "T. Jour2"; (*Journal abbreviation*)

article[s_List] := StringForm["\\bibitem{``} ``, \\textit{``},
                                   `` \\textbf{``}, `` (``).", 
 authornames[s[[2]]], s[[3]], abbvr[s[[4]]], s[[5]], 
 StringSplit[s[[6]], "-"][[1]], s[[7]]]

article[entry["a2"]]

\bibitem{a2} F. L1name, and F. M. L2name, \textit{The title of the work}, T. Jour2 \textbf{2}, 204 (1994).

and you are ready to go. It is much easier than messing with a gigantic .bst file.

$\endgroup$
2
  • $\begingroup$ Are there newlines (\n's) hidden in the string after every comma? $\endgroup$
    – march
    Commented Jun 28, 2016 at 15:23
  • $\begingroup$ you are right @march (did not thought about that before). I put the InputForm in my question. $\endgroup$
    – Sumit
    Commented Jun 28, 2016 at 16:37

1 Answer 1

4
$\begingroup$

This looks like a job for associations:

input = "article{a2,author={F1name L1name,F2name M2name,L2name},
 title={The title of the work},
 journal={The Journal2},year=1994,
 number=3,pages={204-223},month=6,
 note={An optional note},volume=2}"

type = StringCases[input, 
     Shortest[StartOfString ~~ t : __ ~~ "{"] :> t][[1]]

"article"

key = StringCases[input, 
  Shortest[StartOfString ~~ __ ~~ "{"] ~~ key : Shortest[__] ~~  "," :> key][[1]]

"a2"

a["a2"] = Association["type" -> type, "key" -> key]

a[key] = Append[a[key],
 Association[
   Flatten[StringCases[
     input, (k : Except["," | "\n"] ..) ~~ "=" ~~ 
       v : ("{" ~~ Except["}"] .. ~~ "}") :> {k -> v}]]]~Join~
 Association[
   Flatten[StringCases[
     input, (k : Except["," | "\n"] ..) ~~ "=" ~~ 
       v : NumberString :> {k -> v}]]]]

 a["a2"]["pages"]

"{204-223}"

$\endgroup$
2
  • $\begingroup$ Thanks george. Actually I missed \n in my question (@march pointed out that). Could you modify your answer for that :). I put the InputForm of the entry in my question. $\endgroup$
    – Sumit
    Commented Jun 28, 2016 at 16:43
  • $\begingroup$ I think the way i did it, it should not care if you have embedded newlines or not. $\endgroup$
    – george2079
    Commented Jun 28, 2016 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.