commit c1641bda4687f5918d2f31bf7fe7f7ba31f19b7d Author: Rik Veenboer Date: Tue Oct 10 14:11:20 2017 +0100 initial commit diff --git a/article.php b/article.php new file mode 100644 index 0000000..0cd455a --- /dev/null +++ b/article.php @@ -0,0 +1,47 @@ + +
 "@article{%s,\n%s\n}\n",
+    'entry' => '  %s = {%s},',
+    'author' => '%s, %s');
+    
+require_once 'remove-accents.php';
+
+function doi_bibtex($sDoi, $mKey = null, $aDuplicates = null, &$aError = null) {
+    global $sAccount, $aTemplate;
+
+    $sUrl = sprintf('http://www.crossref.org/openurl/?id=%s&noredirect=true&pid=%s&format=unixref', urlencode(trim($sDoi)), $sAccount);
+    if (!($sContents = file_get_contents($sUrl))) {
+        $aError[] = $sDoi;
+        return false;
+    }
+    
+    $oXml = new SimpleXMLElement($sContents);
+    $oCrossrefXml = $oXml->doi_record->crossref;
+    if ($oCrossrefXml === null || isset($oCrossrefXml->error)) {
+        $aError[] = $sDoi;
+        return false;
+    }
+    $oJournalXml = $oCrossrefXml->journal;
+    $oArticleXml = $oJournalXml->journal_article;
+
+    $aAuthors = array();
+    if (isset($oArticleXml->contributors)) {
+        foreach ($oArticleXml->contributors->person_name as $oPersonXml) {
+            $aAuthors[] = sprintf($aTemplate['author'], $oPersonXml->surname, $oPersonXml->given_name);
+        }
+    }
+
+    $oIssueXml = $oJournalXml->journal_issue;
+    $sAuthors = implode(' and ', $aAuthors);
+    $sAuthorsAccentless = remove_accents($sAuthors);
+    if (!isset($oIssueXml->publication_date)) {
+        $aError[] = $sDoi;
+        return false;
+    }
+    $iYear = intval($oIssueXml->publication_date->year);
+    
+    if (is_string($mKey)) {
+        $sKey = $mKey;
+    } else {
+        $aFound = array();
+        if (isset($mKey[$iYear])) {
+            foreach ($mKey[$iYear] as $sAuthor) {
+                if (strpos(str_replace(' ', null, $sAuthorsAccentless), $sAuthor) !== false) {
+                    $sKey = sprintf('%s%d%s', $sAuthor, $iYear, isset($aDuplicates[$iYear][$sAuthor]) ? $aDuplicates[$iYear][$sAuthor] : null);
+                    $aFound[] = $sKey;
+                }
+            }    
+        }
+        $sKey = empty($aFound) ? md5($sDoi) : implode(';', $aFound);
+    }
+
+    $aEntries = array();
+    $aEntries[] = sprintf($aTemplate['entry'], 'author', $sAuthors);
+    $aEntries[] = sprintf($aTemplate['entry'], 'title', trim($oArticleXml->titles->title));
+    $oMetadataXml = $oJournalXml->journal_metadata;
+    $aEntries[] = sprintf($aTemplate['entry'], 'journal', $oMetadataXml->full_title);
+    
+    $aEntries[] = sprintf($aTemplate['entry'], 'year', $iYear);
+    $aEntries[] = sprintf($aTemplate['entry'], 'volume', $oIssueXml->journal_volume->volume);
+    $sPages = empty($oArticleXml->pages->last_page)
+        ? $oArticleXml->pages->first_page
+        : sprintf('%d-%d', $oArticleXml->pages->first_page, $oArticleXml->pages->last_page);
+    $aEntries[] = sprintf($aTemplate['entry'], 'pages', $sPages);
+    $aEntries[] = sprintf($aTemplate['entry'], 'number', $oIssueXml->issue);
+    $aEntries[] = sprintf($aTemplate['entry'], 'month', $oIssueXml->publication_date->month);
+    $aEntries[] = sprintf($aTemplate['entry'], 'doi', $sDoi);
+    $aEntries[] = sprintf($aTemplate['entry'], 'url', $oArticleXml->doi_data->resource);
+
+    return sprintf($aTemplate['article'], $sKey, implode("\n", $aEntries));
+}
\ No newline at end of file
diff --git a/check.php b/check.php
new file mode 100644
index 0000000..11f29ce
--- /dev/null
+++ b/check.php
@@ -0,0 +1,80 @@
+loadFile($sBibtexFile) && $oBibtex->parse()) {
+        foreach ($oBibtex->data as $aEntry) {
+            if ($aEntry['type'] != 'comment') {
+                $aEntries[] = $aEntry['cite'];
+            }
+        }
+    }
+} else {
+    $aEntries = explode("\n", file_get_contents($sEntriesFile));
+}
+
+/* Prepare temporary directory */
+@mkdir($sTmpDir);
+chdir($sTmpDir);
+copy($sBibtexFile, 'reference.bib');
+
+/* Loop over entries */
+@unlink($sFailFile);
+foreach ($aEntries as $iKey => $sEntry) {
+    if (!empty($sEntry)) {
+        printf('Checking "%s"... ', $sEntry);
+        command('rm check*.*');
+        file_put_contents('check.tex', sprintf($sLatex, $sEntry));
+        command('latex -interaction=nonstopmode check');
+        command('bibtex check');
+        command('latex -interaction=nonstopmode check');
+        $sLog = file_get_contents('check.log');
+        if (strpos($sLog, 'inputenc Error') === false) {        
+            printf("success!\n");
+            unset($aEntries[$iKey]);
+        } else {
+            printf("fail!\n");
+            file_put_contents($sFailFile, sprintf("%s\n", $sEntry), FILE_APPEND);
+        }
+    }
+}
+
+/* Clean up */
+command('rm check*.*');
+unlink('reference.bib');
+
+/* Keep track of failed files */
+file_put_contents($sEntriesFile, implode("\n", $aEntries));
+
+/* Helper functions */
+function command($sCommand) {
+    ob_start();
+    exec(sprintf('%s 2>&1', $sCommand));
+    return ob_get_clean();
+}
\ No newline at end of file
diff --git a/consistency.php b/consistency.php
new file mode 100644
index 0000000..2a5f433
--- /dev/null
+++ b/consistency.php
@@ -0,0 +1,134 @@
+
 array( # entries without citation
+        'Schmidbaur2002a',
+        'Anderson2011',
+        'Cadierno2012',
+        'Selander2017a'
+    ),
+    'keys' => array( # entries without file
+        'Finkelstein1910',
+        'Williamson1851',
+        'Ullmann1901',
+        'Ullmann1904',        
+        'Saito1973',
+        'Lee1991',
+        'Hayashi2012',
+        'Rix1956',
+        'Sheldrick2008',        
+        'Smykalla1991',
+        'Kuzmina1994',
+        'Tanisaki1973',
+        'Hayton2010',
+        'Cadierno2013',
+        'Gutmann1975',
+        'Schwerdtfeger1993'
+    ),
+    'type' => array(
+        'online',
+        'book',
+        'inbook',
+        'incollection',
+        'phdthesis'));
+
+/* Load dependencies */
+set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), '../../')));
+require_once 'vendor/autoload.php';
+require_once 'explore.php';
+require_once 'pdf2text.php';
+
+use ZendPdf\PdfDocument;
+use ZendPdf\Exception\CorruptedPdfException;
+use ZendPdf\Exception\NotImplementedException;
+
+preg_match_all('~@([^{]+){([^,]+),~i', $sDatabase, $aMatches);
+
+$aEntries = array_combine($aMatches[2], $aMatches[1]);
+$aDois = array();
+
+echo "No entry found for:\n";
+explore($sFiles, '\*.pdf', $aFound);
+
+$aKeys = [];
+foreach ($aFound as $sFile) {
+    $sBase = basename($sFile, '.pdf');
+    if (ctype_upper(substr($sBase, 0, 1)) && substr($sBase, -2, 1) !== '.' && strpos($sBase, ' ') === false && in_array($sBase, $aMissing['file']) === false) {
+        $bIgnore = false;
+        foreach ($aIgnore as $sIgnore) {
+            if (strpos($sFile, sprintf('%s\\', $sIgnore)) !== false) {
+                $bIgnore = true;
+                break;
+            }
+        }
+        if (!$bIgnore) {
+            $aKeys[] = $sBase;
+        }
+
+        $bEntry = isset($aEntries[$sBase]);
+        if ($bIgnore || $bEntry) {
+            unset($aEntries[$sBase]);
+        } else {
+            if ($bDois) {
+                $sDoi = null;
+                try {
+                    $oPdf = new PdfDocument($sFile, 0, true);
+                    if (isset($oPdf->properties['WPS-ARTICLEDOI'])) {
+                        $sDoi = $oPdf->properties['WPS-ARTICLEDOI'];
+                    }
+                } catch (CorruptedPdfException $e) {
+                } catch (NotImplementedException $e) {}
+
+                if (isset($sDoi)) {
+                    $aDois[] = $sDoi;
+                } elseif ($bText) {
+                    $sText = pdf2text($sFile);
+                    if (preg_match('~(dx\.doi\.org/|doi:\s?)(\d+\.\d+/(:?\w+\.)?\w+)~i', $sText, $aMatch)) {
+                        $aDois[] = $aMatch[2];
+                    } else if (preg_match('~\s(\d+\.\d+/(:?\w+\.)?\w+)CCC~i', $sText, $aMatch)) {
+                        $aDois[] = $aMatch[1];
+                    } else if ($bLoose && preg_match('~(\d{2}\.\d+/\s*(:?\w+\.)?\w+)~i', $sText, $aMatch)) {
+                        $aDois[] = str_replace(' ', null, $aMatch[0]);
+                    }
+                }
+            }
+            if ($bLink) {
+                printf("%-20s (%s)\n", $sBase, $sFile, str_replace(array($sFiles, basename($sFile)), null, $sFile));
+            } else {
+                printf("%s\n", $sBase);
+            }
+        }
+    }
+}
+
+foreach ($aEntries as $sBase => $sType) {
+    if (in_array(strtolower($aEntries[$sBase]), $aMissing['type']) || strpos($sBase, 'ange_') === 0) {
+        unset($aEntries[$sBase]);
+    }
+}
+
+echo "\nDOIs:\n";
+echo count($aDois) > 0 ? implode("\n", $aDois) . "\n" : null;
+
+echo "\nFile missing for:\n";
+echo implode("\n", array_diff(array_keys($aEntries), $aMissing['keys'])). "\n";
+
+// print_r(array_unique($aKeys));
+// print_r(($aKeys));
+echo "\nDuplicate files:\n";
+echo implode("\n", array_diff_assoc($aKeys, array_unique($aKeys)));
\ No newline at end of file
diff --git a/crystals.php b/crystals.php
new file mode 100644
index 0000000..e375d97
--- /dev/null
+++ b/crystals.php
@@ -0,0 +1,29 @@
+', $sContents);
+    if (!isset($aParts[3])) continue;
+    $sJavascript = trim(current(explode('', $aParts[3])));
+    preg_match_all('~"([\w]+)":\s*"([^"]+)"~', $sJavascript, $aMatches, PREG_PATTERN_ORDER);
+    $aData = [];
+    $aHead = array_unique(array_merge($aHead, $aMatches[1]));
+    foreach ($aMatches[1] as $iKey => $sKey) {
+        $aData[$sKey] = $aMatches[2][$iKey];
+    }
+    $aEntries[] = $aData;
+    printf("%s\n", $aData['RefCode']);
+}
+file_put_contents($sData, implode("\t", $aHead) . PHP_EOL);
+$aEmpty = array_flip($aHead);
+foreach ($aEntries as $aEntry) {
+    $aEntry = array_merge($aEmpty, $aEntry);
+    file_put_contents($sData, implode("\t", $aEntry) . PHP_EOL, FILE_APPEND);    
+}
\ No newline at end of file
diff --git a/duplicates.php b/duplicates.php
new file mode 100644
index 0000000..143d8b3
--- /dev/null
+++ b/duplicates.php
@@ -0,0 +1,67 @@
+
 $aFiles) {
+    $iCount = count($aFiles);
+    if ($iCount > 1) {
+        if (defined('NEED')) {
+            $bFound = false;
+            foreach ($aFiles as $sFile) {
+                if (basename($sFile) == NEED) {
+                    $bFound = true;
+                }
+            }
+            if (!$bFound) {
+                continue;
+            }
+        }
+        ++$iRepeated;
+        $sBuffer .= sprintf("%s=%d\n", $sCite, $iCount);
+        foreach ($aFiles as $sFile) {
+            $sBuffer .= sprintf("    - %s\n", $sFile);
+        }
+    }
+    if (isset($aStats[$iCount])) {
+        ++$aStats[$iCount];
+    } else {
+        $aStats[$iCount] = 1;
+    }
+}
+
+printf("Total number of unique citations: %d\n\n", count($aCites));
+printf("Number of repeated citations: %d\n\n", $iRepeated);
+printf("%s\n\n", $sBuffer);
+
+ksort($aStats);
+foreach ($aStats as $iCount => $iNumber) {
+    printf("%d > %d\n", $iCount, $iNumber);
+}
\ No newline at end of file
diff --git a/file.php b/file.php
new file mode 100644
index 0000000..6279f2a
--- /dev/null
+++ b/file.php
@@ -0,0 +1,40 @@
+
 $sOriginal) {
+    $sKey = $aMatches[1][$i];
+    if (isset($aFiles[$sKey])) {        
+        $sFile = str_replace('\\', '\\\\', $aFiles[$sKey]);
+        $sField = sprintf(':%s:PDF', $sFile);
+        $sNew = preg_replace('~[\s]*file[\s]*=[\s]*\{[^\}]*\},?([\n\r])+~', '$1', $sOriginal);
+        $aFields = explode(',', $sNew);
+        $sNew = rtrim($sNew, "\n\r}");
+        if (substr($sNew, -1) !== ',') {
+            $sNew .= '},';
+        }
+        $sNew = sprintf("%s\nfile = {%s}\n}", $sNew, $sField);
+        $sDatabase = str_replace($sOriginal, $sNew, $sDatabase);
+    }
+}
+file_put_contents($sBibliography, $sDatabase);
\ No newline at end of file
diff --git a/fix.php b/fix.php
new file mode 100644
index 0000000..4353510
--- /dev/null
+++ b/fix.php
@@ -0,0 +1,14 @@
+
 $sOriginal) {
+    preg_match_all('~[\s]+volume[\s]*=[\s]*\{.*?\},~si', $sOriginal, $aVolumes);
+    $iCount = count($aVolumes[0]);
+    if ($iCount > 1) {
+        printf("Deleting %d volume fields from %s!\n", $iCount, $aMatches[1][$i]);
+        $sNew = str_replace($aVolumes[0], null, $sOriginal);
+        $sDatabase = str_replace($sOriginal, $sNew, $sDatabase);
+    }
+}
+file_put_contents($sFile, $sDatabase);
\ No newline at end of file
diff --git a/formchk.php b/formchk.php
new file mode 100644
index 0000000..798b8a4
--- /dev/null
+++ b/formchk.php
@@ -0,0 +1,15 @@
+ 0) {
+        $aEntries[$sKey] = $aMatch[1];
+    }
+}
+
+preg_match_all('~@comment\{([^\}]+)\}~s', $sContents, $aMatches);
+$aGroups = array();
+foreach ($aMatches[1] as $sComment) {
+    $aParts = explode(';', $sComment);
+    $aType = explode(':', array_shift($aParts));
+    if (trim($aType[0]) == 'jabref-meta' && trim($aType[1]) == 'groupstree') {
+        foreach ($aParts as $sPart) {
+            $sPart = str_replace(array('\\', "\r", "\n"), null, trim($sPart));
+            if (!empty($sPart)) {
+                if (preg_match('~group:(.+)~i', $sPart, $aMatch) > 0) {
+                    $sGroup = $aMatch[1];
+                    $sSearch = $sGroup;//str_replace(array('Thesis'), array('Theses'), $sGroup);
+
+                    $aGroup = array($sPart . '\\;0\\');
+                    foreach ($aEntries as $sKey => $sPdf) {
+
+                        if (strpos($sPdf, $sSearch) !== false) {
+                            $aGroup[] = $sKey . '\\';
+                        }
+                    }
+                    $aGroup[] = null;
+                    $aGroups[] = implode(';', $aGroup);
+                }
+            }
+        }
+    }
+}
+echo implode(";\n", $aGroups);
\ No newline at end of file
diff --git a/nmr.php b/nmr.php
new file mode 100644
index 0000000..b3dc156
--- /dev/null
+++ b/nmr.php
@@ -0,0 +1,140 @@
+

+
loadFile($sFile) && $oBibtex->parse()) {
+    foreach ($oBibtex->data as $aEntry) {
+        $bPages = isset($aEntry['pages']);
+        if ($aEntry['type'] == 'article' && isset($aEntry['doi'])) {
+            $bDoi = $bPages && strpos($aEntry['pages'], 'doi') !== false;
+            if (!$bUpdateDoi || ($bPages && $aEntry['pages'] != '0-0' && $aEntry['pages'] != '0' && (is_numeric($aEntry['pages']) ? $aEntry['pages'] < 1000000 : true) && !$bDoi)) {
+                continue;            
+            }
+            $sCite = $aEntry['cite'];
+            $sDoi = $aEntry['doi'];
+            printf("Processing %s (%s)...\n", $sCite, $bPages ? $aEntry['pages'] : null);
+
+            preg_match(sprintf('~@article\{%s,.*?\}[\s]*\}~si', $sCite), $sDatabase, $aMatch);
+            if (!isset($aMatch[0])) {
+                printf("Entry not found!\n");
+                continue;
+            }
+            $sOriginal = $aMatch[0];
+            $sUrl = sprintf('http://www.crossref.org/openurl/?id=%s&noredirect=true&pid=%s&format=unixref', urlencode(trim($sDoi)), $sAccount);
+            if (!($sContents = file_get_contents($sUrl))) {
+                printf("Failed to fetch reference!\n");
+                continue;
+            }
+            if (strpos($sContents, 'Malformed DOI') !== false) {
+                echo "error!\n";
+                continue;
+            }
+            $oXml = new SimpleXMLElement($sContents);            
+            $oCrossrefXml = $oXml->doi_record->crossref;
+            $oJournalXml = $oCrossrefXml->journal;
+            $oArticleXml = $oJournalXml->journal_article;
+            if ($oCrossrefXml === null || isset($oCrossrefXml->error)) {
+                printf("Corrupt reference!\n");
+                continue;
+            }
+            $oArticleXml = $oJournalXml->journal_article;
+            $sPages = ($bSingle = empty($oArticleXml->pages->last_page))
+                ? $oArticleXml->pages->first_page
+                : sprintf('%d-%d', $oArticleXml->pages->first_page, $oArticleXml->pages->last_page);
+            if ($sPages == '0-0' || $sPages == '0' || empty($sPages) || ($bSingle && $sPages > 100000)) {
+                if ($bDoi) {
+                    continue;
+                }
+                $sPages = sprintf('doi: %s', $sDoi);
+            }
+            printf("Set to: %s\n", $sPages);
+            if (isset($aEntry['pages'])) {
+                $sNew = str_replace(
+                    $aEntry['pages'],
+                    $sPages,
+                    $sOriginal);
+            } else {
+                $sNew = str_replace(
+                    sprintf('%s,', $sCite),
+                    sprintf("%s,\npages = {%s},", $sCite, $sPages),
+                    $sOriginal);
+            }
+            $sDatabase = str_replace($sOriginal, $sNew, $sDatabase);
+        }
+    }
+}
+file_put_contents($sFile, $sDatabase);
\ No newline at end of file
diff --git a/remove-accents.php b/remove-accents.php
new file mode 100644
index 0000000..5c8e893
--- /dev/null
+++ b/remove-accents.php
@@ -0,0 +1,106 @@
+ 'A', chr(195).chr(129) => 'A',
+    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
+    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
+    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
+    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
+    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
+    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
+    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
+    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
+    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
+    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
+    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
+    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
+    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
+    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
+    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
+    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
+    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
+    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
+    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
+    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
+    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
+    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
+    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
+    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
+    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
+    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
+    chr(195).chr(191) => 'y',
+    // Decompositions for Latin Extended-A
+    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
+    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
+    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
+    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
+    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
+    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
+    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
+    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
+    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
+    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
+    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
+    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
+    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
+    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
+    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
+    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
+    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
+    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
+    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
+    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
+    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
+    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
+    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
+    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
+    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
+    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
+    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
+    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
+    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
+    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
+    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
+    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
+    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
+    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
+    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
+    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
+    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
+    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
+    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
+    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
+    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
+    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
+    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
+    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
+    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
+    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
+    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
+    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
+    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
+    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
+    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
+    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
+    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
+    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
+    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
+    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
+    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
+    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
+    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
+    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
+    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
+    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
+    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
+    chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
+    );
+
+    $sString = strtr($sString, $aChars);
+    return $sString;
+}
\ No newline at end of file
diff --git a/rss-science.php b/rss-science.php
new file mode 100644
index 0000000..d1d6931
--- /dev/null
+++ b/rss-science.php
@@ -0,0 +1,11 @@
+item) - 1; $i >= 0; --$i) {
+	$oItemXml = $oXml->item[$i];
+	if (strpos($oItemXml->title, 'Chemistry:') === false) {
+		unset($oXml->item[$i]);
+	}
+}
+echo $oXml->asXML();
\ No newline at end of file
diff --git a/sambvca.php b/sambvca.php
new file mode 100644
index 0000000..e720b49
--- /dev/null
+++ b/sambvca.php
@@ -0,0 +1,67 @@
+
([^\<]+)~', $sResponse, $aMatches);
+        $fValue = isset($aMatches[1][1]) ? $aMatches[1][1] : 0;
+        printf("%s (%s) = %.1f\n", $sPart, $bDeleteGold ? 'true' : 'false', $fValue);
+    }
+}
+
+function execute($sFile, $bDeleteGold = true) {
+    $aData = array (
+      'action' => 'upload',
+      'xyzinput' => 'upload',
+      'radii' => 'bondi2',
+      'atom_center' => '1',
+      'atom_axis' => '2',
+      'atom_plane' => '2',
+      'propC2' => '1.80',
+      'propC3' => '2.00',
+      'propN2' => '1.65',
+      'propN3' => '1.87',
+      'propP' => '1.90',
+      'propH' => '1.20',
+      'atom_coord' => '0',
+      'atom_indexes' => '0 1',
+      'which_axis' => '6',
+      'plane_indexes' => '0 2',
+      'atom_todelete' => $bDeleteGold ? 0 : null,
+      'atoms_radius' => '1',
+      'radius' => '3.5',
+      'distance' => '0.0',
+      'i_step' => '0.10',
+      'submit_button' => 'submit',
+    );
+    $sUrl = 'https://www.molnac.unisa.it/OMtools/sambvca2.0/process/sambvca_result.php';
+    $aData['input_file'] = trim(file_get_contents($sFile));
+    $aData['input_file_handle'] = new CURLFile(realpath($sFile));
+    $rCurl = curl_init();
+    curl_setopt($rCurl, CURLOPT_URL, $sUrl);
+    curl_setopt($rCurl, CURLOPT_FOLLOWLOCATION, true);
+    curl_setopt($rCurl, CURLOPT_SSL_VERIFYPEER, false);
+    curl_setopt($rCurl, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($rCurl, CURLOPT_POST, true);
+    curl_setopt($rCurl, CURLOPT_POSTFIELDS, $aData);
+    $sResponse = curl_exec($rCurl);
+    curl_close($rCurl);
+    // file_put_contents('result.html', $sResponse);
+    // $sResponse = file_get_contents('result.html');
+    $sResponse = str_replace(
+        array(''),
+        array(''),
+        $sResponse);
+    // $sResponse = preg_replace('#(.*?)#is', '', $sResponse);
+    return $sResponse;
+}
\ No newline at end of file
diff --git a/topspin.php b/topspin.php
new file mode 100644
index 0000000..08710cb
--- /dev/null
+++ b/topspin.php
@@ -0,0 +1,24 @@
+ $sBase) {
+    $sFormatted = sprintf('%s:/%s', substr($sDirectory, 0, 1), str_replace('\\', '/', substr($sDirectory, 3)));
+    $aContents[] = sprintf('%d=%s/%s\=alias\=%3$s', $i, $sFormatted, $sBase, $sBase);
+    
+}
+file_put_contents($sTopspin, implode("\n", $aContents));
\ No newline at end of file
diff --git a/volume.php b/volume.php
new file mode 100644
index 0000000..1485329
--- /dev/null
+++ b/volume.php
@@ -0,0 +1,72 @@
+
+
loadFile($sFile) && $oBibtex->parse()) {
+    foreach ($oBibtex->data as $aEntry) {
+        if ($aEntry['type'] == 'article' && isset($aEntry['doi'])) {
+            if (isset($aEntry['volume'])) {
+               continue;            
+            }
+            $sCite = $aEntry['cite'];
+            $sDoi = $aEntry['doi'];
+            printf("Processing %s...\n", $sCite);
+            preg_match(sprintf('~@article\{%s,.*?\}[\s]*\}~si', $sCite), $sDatabase, $aMatch);
+            if (!isset($aMatch[0])) {
+                printf("Entry not found!\n");
+                continue;
+            }
+            $sOriginal = $aMatch[0];
+            $sUrl = sprintf('http://www.crossref.org/openurl/?id=%s&noredirect=true&pid=%s&format=unixref', urlencode(trim($sDoi)), $sAccount);
+            if (!($sContents = file_get_contents($sUrl))) {
+                printf("Failed to fetch reference!\n");
+                continue;
+            }
+            $oXml = new SimpleXMLElement($sContents);            
+            $oCrossrefXml = $oXml->doi_record->crossref;
+            if ($oCrossrefXml === null || isset($oCrossrefXml->error)) {
+                printf("Corrupt reference!\n");
+                continue;
+            }
+            $oJournalXml = $oCrossrefXml->journal;
+            $oArticleXml = $oJournalXml->journal_article;            
+            $oIssueXml = $oJournalXml->journal_issue;
+            if (isset($oIssueXml->journal_volume->volume)) {
+                $iVolume = trim($oIssueXml->journal_volume->volume);
+                $iYear = intval($oIssueXml->publication_date->year);
+                $oMetadataXml = $oJournalXml->journal_metadata;
+                $sJournal = $oMetadataXml->full_title;
+                if ($sJournal == 'Eur. J. Org. Chem.' || $sJournal == 'Eur. J. Inorg. Chem.') {        
+                    printf("Notorious journal (%s), skipping!\n", $sJournal);
+                    continue;
+                }
+                if ($iVolume == $iYear) {                    
+                    printf("Volume and year match, skipping!\n", $iVolume);
+                    continue;
+                }
+                if (strlen($iVolume) > 0) {
+                    printf("Set to: %s\n", $iVolume);
+                    $sNew = str_replace('doi =', sprintf("volume = {%s},\n doi =", $iVolume), $sOriginal);
+                    $sDatabase = str_replace($sOriginal, $sNew, $sDatabase);
+                     if (++$iCount > 250) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+file_put_contents($sFile, $sDatabase);
\ No newline at end of file
diff --git a/xyz.php b/xyz.php
new file mode 100644
index 0000000..c80fd3f
--- /dev/null
+++ b/xyz.php
@@ -0,0 +1,11 @@
+