From 768278c234a50d13614b96ba1fdcfd8671b4ad2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20P?= Date: Mon, 8 Jan 2024 16:02:29 +0100 Subject: [PATCH] Write BibTeX to file --- MainWindow.xaml | 11 ++++-- MainWindow.xaml.cs | 19 +++++----- Records.cs | 27 +++++++++++++- Text2Bib.cs | 85 ++++++++++++++++++-------------------------- Txt2Bib.csproj | 2 ++ openfolder_4896.png | Bin 0 -> 8342 bytes 6 files changed, 81 insertions(+), 63 deletions(-) create mode 100644 openfolder_4896.png diff --git a/MainWindow.xaml b/MainWindow.xaml index 5fd0ec1..c1905a3 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -5,12 +5,12 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Txt2Bib" mc:Ignorable="d" - Title="MainWindow" Height="718" Width="800"> - + Title="MainWindow" Height="744" Width="800"> + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 9e0443b..44139ff 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -1,17 +1,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Txt2Bib { @@ -75,7 +68,10 @@ namespace Txt2Bib private void GoBtn_Click(object sender, RoutedEventArgs e) { var txt2bib = new Text2Bib(); - Debug.Text = txt2bib.Generate(DropArea.Text); + var result = txt2bib.Generate(DropArea.Text); + Debug.Text = result; + using var outputFile = new StreamWriter("output_bibtex.bib"); + outputFile.Write(result); } private void CopyDebug_Click(object sender, RoutedEventArgs e) @@ -83,5 +79,10 @@ namespace Txt2Bib Debug.SelectAll(); Debug.Copy(); } + + private void OpenDestFolderBtn_Click(object sender, RoutedEventArgs e) + { + System.Diagnostics.Process.Start("explorer.exe", Directory.GetCurrentDirectory()); + } } } diff --git a/Records.cs b/Records.cs index 103b93f..a036e40 100644 --- a/Records.cs +++ b/Records.cs @@ -21,6 +21,31 @@ namespace Txt2Bib.Records public string Doi { get; set; } = ""; public string Url { get; set; } = ""; + public string Convert(string[] entryLines) + { + var temp = entryLines[1].Split(','); + var rearrange = (string a) => + { + a = a.Trim(); + var s = a.Split(' '); + return $"{s[1]} {s[0]}"; + }; + Author = temp.Select(a => rearrange(a)).ToArray(); + Year = ushort.Parse(entryLines[2]); + Title = entryLines[3]; + Journal = entryLines[4]; + Volume = entryLines[5].Split(',').Length == 2 ? + byte.Parse(entryLines[5].Split(',')[0]) : + byte.Parse(entryLines[5]); + Issue = entryLines[5].Split(',').Length == 2 ? + byte.Parse(entryLines[5].Split(',')[1]) : null; + FirstPage = ushort.Parse(entryLines[6].Split('-')[0]); + LastPage = ushort.Parse(entryLines[6].Split('-')[1]); + Doi = entryLines.Length > 7 ? entryLines[7] : ""; + + return ToString(); + } + public override string ToString() { return $"@{Type}" + "{" +$"{Author[0][..5]}_{Year},\n" + @@ -51,7 +76,7 @@ namespace Txt2Bib.Records { return $"@{Type}" + "{" +$"{Author[0][..5]}_{Year},\n" + $"\tauthor = \"{string.Join(" and", Author)}\",\n" + - $"\ttitle = \"{Title}\",\n" + + $"\ttitle = {{{Title}}},\n" + $"\tpublisher = \"{Publisher}\",\n" + $"\taddress = \"{Place}\",\n" + $"\tyear = \"{Year}\",\n" + diff --git a/Text2Bib.cs b/Text2Bib.cs index a0422b6..93c94bf 100644 --- a/Text2Bib.cs +++ b/Text2Bib.cs @@ -3,23 +3,19 @@ using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; -using System.Windows.Controls.Primitives; -using System.Windows; using Txt2Bib.Records; -using System.ComponentModel.DataAnnotations; +using System.Windows; +using System.Runtime.CompilerServices; +using System.CodeDom; namespace Txt2Bib { - internal class Text2Bib + /// + /// Converting entries from text file to BibTeX format + /// + public class Text2Bib { - private readonly Dictionary _citTypes = new() - { - { "J" , "article" }, - { "B", "book" }, - { "P", "conference" }, - { "C" , "inbook" } - }; + private string[] _citTypes = { "J", "B", "C", "P", "?" }; /// /// Generate single .bib file from input text files /// @@ -39,10 +35,15 @@ namespace Txt2Bib result += Encoding.Latin1.GetString(contentBytes); } - var entries = result.Split('%').ToList().Select(entry => + IEnumerable entries = new List(); + try { - return Process(entry); - }); + entries = result.Split('%').ToList().Select(entry => Process(entry)); + } + catch (Exception) + { + throw; + } foreach (var entry in entries) { @@ -51,56 +52,40 @@ namespace Txt2Bib return output; } - - private string Process(string entryFromTxt) + /// + /// Creates a bib entry from source text + /// + /// Handle exception + /// + /// + /// Invalid citation type for this entry + public string Process(string entryFromTxt) { var lines = entryFromTxt.Trim().Replace("\r", string.Empty).Split("\n"); - var type = lines.First(); + var type = lines.First().Trim(); - System.Diagnostics.Debug.WriteLine($"Entry: {entryFromTxt}; Prima riga: {type}"); + if (!IsValidEntry(type)) throw new Exception($"Invalid entry type '{type}'"); string citation = type switch { - "J" => ConvertArticle(lines), + "J" => (new ArticleBib()).Convert(lines), //"B" => new BookBib(), //"C" => new ChapterBib(), //"P" => new ConferenceBib(), - _ => ConvertArticle(lines), + _ => (new ArticleBib()).Convert(lines) }; return citation; } - - private static string ConvertArticle(string[] entryLines) + /// + /// Validate txt entry based + /// on citation types + /// + /// + protected bool IsValidEntry(string entryType) { - var temp = entryLines[1].Split(','); - var rearrange = (string a) => - { - a = a.Trim(); - var s = a.Split(' '); - return $"{s[1]} {s[0]}"; - }; - var authors = temp.Select(a => rearrange(a)).ToArray(); - var article = new ArticleBib - { - Author = authors, - Year = ushort.Parse(entryLines[2]), - Title = entryLines[3], - Journal = entryLines[4], - // TODO split with ',' for issue - Volume = entryLines[5].Split(',').Length == 2 ? - byte.Parse(entryLines[5].Split(',')[0]) : - byte.Parse(entryLines[5]), - Issue = entryLines[5].Split(',').Length == 2 ? - byte.Parse(entryLines[5].Split(',')[1]) : null, - FirstPage = ushort.Parse(entryLines[6].Split('-')[0]), - LastPage = ushort.Parse(entryLines[6].Split('-')[1]), - Doi = entryLines.Length > 7 ? entryLines[7] : "", - }; - - return article.ToString(); + return _citTypes.Contains(entryType); } - /// /// TODO: How to determine correct encoding of text file?? /// diff --git a/Txt2Bib.csproj b/Txt2Bib.csproj index 261334f..a163a13 100644 --- a/Txt2Bib.csproj +++ b/Txt2Bib.csproj @@ -9,10 +9,12 @@ + + diff --git a/openfolder_4896.png b/openfolder_4896.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d62813f0de47b0a37631057c44de7f99e4400d GIT binary patch literal 8342 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 literal 0 HcmV?d00001