let str ~pattern ?(transform_text:text_transformation= `no) (set:Biblio.set) =
    let rex_field = Pcre.regexp "@\\{[^\\}]+\\}" in

    let strfield ?authors_style ?title_style f e =
      let str = Biblio.field_or_empty ?authors_style ?title_style f e in
      do_sanitization transform_text str in
    let sub_eq s i o m =
      if String.length s < o + i then false else (String.sub s i o =$= m) in
    let is_write stack =
      Stack.is_empty stack || Stack.top stack =@= `write in
    let subs stack entry = function
      | "@{id}" when is_write stack ->  strfield `id entry
      | "@{authors}" when is_write stack -> strfield `authors entry
      | "@{authors-and}" when is_write stack ->
          strfield ~authors_style:`comas_and `authors entry 
      | "@{authors-bibtex}" when is_write stack ->
          strfield ~authors_style:`bibtex `authors entry 
      | "@{authors-acm}" when is_write stack -> 
          strfield ~authors_style:`acm `authors entry 
      | "@{authors-etal}" when is_write stack -> 
          strfield ~authors_style:`et_al `authors entry 
      | "@{title}" when is_write stack -> strfield `title entry 
      | "@{title-punct}" when is_write stack -> 
          strfield ~title_style:`punct `title entry 
      | "@{how}" when is_write stack -> strfield `how entry 
      | "@{year}" when is_write stack -> strfield `year entry 
      | "@{url}"      when is_write stack -> strfield `url       entry 
      | "@{pdfurl}"   when is_write stack -> strfield `pdfurl    entry 
      | "@{comment}" when is_write stack ->
          strfield (`comment "main") entry
      | s when sub_eq s 0 10 "@{comment-" ->
          let lgth = Str.length s in
          let opt = (Str.sub s 10 (lgth - 11)) in
          strfield (`comment opt) entry
      | "@{bibtex}"   when is_write stack -> BibTeX.format_entry entry 
      | "@{abstract}" when is_write stack -> strfield `abstract  entry 
      | "@{doi}"      when is_write stack -> strfield `doi       entry 
      | "@{citation}" when is_write stack -> strfield `citation  entry 
      | "@{tags}"     when is_write stack -> strfield `tags      entry 
      | "@{keywords}" when is_write stack -> strfield `keywords  entry 
      | "@{@}" when is_write stack -> "@" 
      | "@{n}" when is_write stack -> "\n" 
      | s when sub_eq s 0 4 "@{if" ->
          let lgth = String.length s in
          let expr = Request.of_string (String.sub s 4 (lgth - 5)) in
          begin match is_write stack, Request.is_ok entry expr with
          | truetrue -> Stack.push `write stack
          | truefalse -> Stack.push `no_write stack
          | false, _ -> Stack.push `silent stack
          end;
          ""
      | "@{else}" -> 
          begin try
            match Stack.pop stack with
            | `write -> Stack.push `no_write stack; ""
            | `no_write -> Stack.push `write stack; ""
            | `silent -> Stack.push `silent stack ; ""
          with e -> failwith "@{else} does not match any @{if ...}"
          end
      | "@{endif}" ->
          begin try
            let _ =  Stack.pop stack in ""
          with e -> failwith "@{endif} does not match any @{if ...}"
          end
      | s -> if is_write stack then s else ""
    in
    String.concat ""
      (Ls.concat 
         (Ls.map
            (fun entry ->
               let stack = Stack.create () in
               Ls.map (function
                       | Pcre.Text t -> if is_write stack then t else ""
                       | Pcre.Delim s -> subs stack entry s
                       | _ -> "")
                 (Pcre.full_split ~rex:rex_field pattern)) set))