= 2) { // Remove opening brace if it exists if ($str[0] === '{') { $str = substr($str, 1); } // After removing first brace, get new length $length = strlen($str); // Remove closing brace if it exists if ($length > 0 && $str[$length - 1] === '}') { $str = substr($str, 0, -1); } } return $str; } function expandJournalAbbreviation($abbrev) { // Define mapping of abbreviations (including LaTeX macros) to full journal names $journalMap = [ // Standard abbreviations 'AJ' => 'The Astronomical Journal', 'ApJ' => 'The Astrophysical Journal', 'ApJL' => 'The Astrophysical Journal Letters', 'ApJS' => 'The Astrophysical Journal Supplement Series', 'ARA&A' => 'Annual Review of Astronomy and Astrophysics', 'ARAA' => 'Annual Review of Astronomy and Astrophysics', 'ARAP' => 'Annual Review of Astronomy and Astrophysics', 'MNRAS' => 'Monthly Notices of the Royal Astronomical Society', 'PASP' => 'Publications of the Astronomical Society of the Pacific', 'PASJ' => 'Publications of the Astronomical Society of Japan', 'A&A' => 'Astronomy & Astrophysics', 'A&AS' => 'Astronomy & Astrophysics Supplement Series', // LaTeX macros '\aj' => 'The Astronomical Journal', '\apj' => 'The Astrophysical Journal', '\apjl' => 'The Astrophysical Journal Letters', '\apjlett' => 'The Astrophysical Journal Letters', '\apjs' => 'The Astrophysical Journal Supplement Series', '\apjsupp' => 'The Astrophysical Journal Supplement Series', '\araa' => 'Annual Review of Astronomy and Astrophysics', '\mnras' => 'Monthly Notices of the Royal Astronomical Society', '\pasp' => 'Publications of the Astronomical Society of the Pacific', '\pasj' => 'Publications of the Astronomical Society of Japan', '\aap' => 'Astronomy & Astrophysics', '\aaps' => 'Astronomy & Astrophysics Supplement Series', '\aapr' => 'Astronomy & Astrophysics Reviews', '\solphys' => 'Solar Physics', '\pasa' => 'Publications of the Astronomical Society of Australia', '\jcap' => 'Journal of Cosmology and Astroparticle Physics', '\nat' => 'Nature', '\science' => 'Science', '\icarus' => 'Icarus', '\prd' => 'Physical Review D', '\prl' => 'Physical Review Letters', '\grl' => 'Geophysical Research Letters', '\jgr' => 'Journal of Geophysical Research', '\baas' => 'Bulletin of the American Astronomical Society', '\physrep' => 'Physics Reports', '\apss' => 'Astrophysics and Space Science' ]; // Clean the input $abbrev = trim($abbrev); // Handle case sensitivity for standard abbreviations if (!str_starts_with($abbrev, '\\') && isset($journalMap[strtoupper($abbrev)])) { $abbrev = strtoupper($abbrev); } // Return the full name if found, otherwise return original abbreviation return $journalMap[$abbrev] ?? $abbrev; } // Function to process text that might contain multiple journal references function expandJournalReferences($text) { // First handle LaTeX macros that might be followed by spaces or punctuation $pattern = '/\\\\[a-zA-Z]+/'; $text = preg_replace_callback($pattern, function($matches) { return expandJournalAbbreviation($matches[0]); }, $text); // Then handle standard abbreviations $words = explode(' ', $text); $result = []; foreach ($words as $word) { if (!str_starts_with($word, 'The ')) { // Avoid re-processing already expanded journals $result[] = expandJournalAbbreviation($word); } else { $result[] = $word; } } return implode(' ', $result); } function convertFirstNameToInitial($name) { // Trim any whitespace $name = trim($name); // Return empty string if name is empty if (empty($name)) { return ''; } // Split the name into parts $parts = preg_split('/\s+/', $name); // Process each part $result = array_map(function($part) { // Skip if part is empty if (empty($part)) { return ''; } // If it's already an initial (single character followed by optional period) if (preg_match('/^[A-Z]\.?$/', $part)) { // Ensure it has a period return rtrim($part, '.') . '.'; } // If it's a hyphenated name, handle each part if (strpos($part, '-') !== false) { $hyphenParts = explode('-', $part); $initials = array_map(function($p) { if (!empty($p)) { return ucfirst($p[0]) . '.'; } return ''; }, $hyphenParts); return implode('-', $initials); } // Regular name: take first character, capitalize it, add period return ucfirst($part[0]) . '.'; }, $parts); // Join the parts back together return implode(' ', array_filter($result)); } $m = setup_mustache(); // Create and configure a Listener $listener = new Listener(); $listener->addProcessor(new Processor\TagNameCaseProcessor(CASE_LOWER)); $listener->addProcessor(new NamesProcessor()); $listener->addProcessor(static function (array $entry) { $entry['title'] = removeBoundingBraces($entry['title']); foreach ($entry['author'] as $i=>$v) { $entry['author'][$i]['first'] = convertFirstNameToInitial($v['first']); $entry['author'][$i]['last'] = removeBoundingBraces($v['last']); } if (isset($entry['journal'])) { $entry['journal'] = expandJournalReferences($entry['journal']); } return $entry; }); //$listener->addProcessor(new LatexToUnicodeProcessor()); // Create a Parser and attach the listener $parser = new Parser(); $parser->addListener($listener); // Parse the content, then read processed data from the Listener try { $parser->parseFile('assets/bib/export-bibtex.bib'); $entries = $listener->export(); $tpl = $m->loadTemplate("publi_bib_html"); echo $tpl->render( array( 'ROOT_URL' => $iap_root, 'title'=>'Guilhem Lavaux\'s publications', 'publi'=>$entries, 'configure_script'=>[ 'MathJax = { tex: { inlineMath: [[\'$\', \'$\'], [\'\\\\(\', \'\\\\)\']] } }; ' ], 'external_scripts'=>[ 'src="https://polyfill.io/v3/polyfill.min.js?features=es6"', 'id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"' ], 'bar' => 'baz')); } catch (Exception $e) { echo $e->getMessage() . "
"; }