From 06b3f67ec22d83427b91a068d338d7225fcbd7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Perlk=C3=B6nig?= Date: Sat, 8 Jul 2017 15:05:27 -0600 Subject: [PATCH] Added word frequency list and made new release --- EditTools/Ribbon1.Designer.cs | 28 +++++++++++++-- EditTools/Ribbon1.cs | 66 ++++++++++++++++++++++++++++++++++ README.md | 7 ++-- deploy/make-installer.iss | 4 +-- screen-capture.jpg | Bin 20191 -> 21281 bytes 5 files changed, 98 insertions(+), 7 deletions(-) diff --git a/EditTools/Ribbon1.Designer.cs b/EditTools/Ribbon1.Designer.cs index c1ccc53..144c190 100644 --- a/EditTools/Ribbon1.Designer.cs +++ b/EditTools/Ribbon1.Designer.cs @@ -51,6 +51,7 @@ private void InitializeComponent() this.group4 = this.Factory.CreateRibbonGroup(); this.dd_Boilerplate = this.Factory.CreateRibbonDropDown(); this.btn_ApplyBoilerplate = this.Factory.CreateRibbonButton(); + this.btn_WordFreq = this.Factory.CreateRibbonButton(); this.EditingTools.SuspendLayout(); this.group1.SuspendLayout(); this.group2.SuspendLayout(); @@ -81,24 +82,29 @@ private void InitializeComponent() // this.btn_Settings.Label = "Settings"; this.btn_Settings.Name = "btn_Settings"; + this.btn_Settings.ScreenTip = "Add/remove/edit boilerplate and configure the edit distance for the proper noun c" + + "hecker"; this.btn_Settings.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_Settings_Click); // // btn_Export // this.btn_Export.Label = "Export"; this.btn_Export.Name = "btn_Export"; + this.btn_Export.ScreenTip = "Save your boilerplate to an XML file you can back up or share"; this.btn_Export.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_Export_Click); // // btn_Import // this.btn_Import.Label = "Import"; this.btn_Import.Name = "btn_Import"; + this.btn_Import.ScreenTip = "Import a boilerplate XML file"; this.btn_Import.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.button1_Click); // // group2 // this.group2.Items.Add(this.dd_Langs); this.group2.Items.Add(this.btn_FixLang); + this.group2.Items.Add(this.btn_SingData); this.group2.Label = "Editing"; this.group2.Name = "group2"; // @@ -106,6 +112,8 @@ private void InitializeComponent() // this.dd_Langs.Label = "Languages"; this.dd_Langs.Name = "dd_Langs"; + this.dd_Langs.ScreenTip = "Apply selected language to the entire document, including notes, headers and foo" + + "ters"; this.dd_Langs.ShowLabel = false; this.dd_Langs.SizeString = "WWWWWWWWWWWWWWW"; // @@ -113,13 +121,15 @@ private void InitializeComponent() // this.btn_FixLang.Label = "Apply Language"; this.btn_FixLang.Name = "btn_FixLang"; + this.btn_FixLang.ScreenTip = "Apply selected language to the entire document, including notes, headers and foo" + + "ters"; this.btn_FixLang.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_FixLang_Click); // // group3 // this.group3.Items.Add(this.btn_WordList); + this.group3.Items.Add(this.btn_WordFreq); this.group3.Items.Add(this.btn_ProperNouns); - this.group3.Items.Add(this.btn_SingData); this.group3.Label = "Proofing"; this.group3.Name = "group3"; // @@ -127,18 +137,22 @@ private void InitializeComponent() // this.btn_WordList.Label = "Word List"; this.btn_WordList.Name = "btn_WordList"; + this.btn_WordList.ScreenTip = "Generate a list of all the unique words in the document"; this.btn_WordList.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_WordList_Click); // // btn_ProperNouns // - this.btn_ProperNouns.Label = "ProperNounAlyze"; + this.btn_ProperNouns.Label = "Check Proper Nouns"; this.btn_ProperNouns.Name = "btn_ProperNouns"; + this.btn_ProperNouns.ScreenTip = "Find proper nouns that sound alike or that differ by a configurable edit distance" + + ""; this.btn_ProperNouns.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_ProperNouns_Click); // // btn_SingData // this.btn_SingData.Label = "Find Singular Data"; this.btn_SingData.Name = "btn_SingData"; + this.btn_SingData.ScreenTip = "Find \"data\" used as a singular noun"; this.btn_SingData.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_SingData_Click); // // grp_Finishing @@ -164,6 +178,7 @@ private void InitializeComponent() // this.dd_Boilerplate.Label = "Comments"; this.dd_Boilerplate.Name = "dd_Boilerplate"; + this.dd_Boilerplate.ScreenTip = "Use the \"Settings\" button to add/remove/edit boilerplate"; this.dd_Boilerplate.ShowLabel = false; this.dd_Boilerplate.SizeString = "WWWWWWWWWWWWWWW"; // @@ -171,8 +186,16 @@ private void InitializeComponent() // this.btn_ApplyBoilerplate.Label = "Apply Comment"; this.btn_ApplyBoilerplate.Name = "btn_ApplyBoilerplate"; + this.btn_ApplyBoilerplate.ScreenTip = "Click to apply selected comment to the selected text; Use the \"Settings\" button t" + + "o add/remove/edit boilerplate"; this.btn_ApplyBoilerplate.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_ApplyBoilerplate_Click); // + // btn_WordFreq + // + this.btn_WordFreq.Label = "Word Frequency List"; + this.btn_WordFreq.Name = "btn_WordFreq"; + this.btn_WordFreq.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btn_WordFreq_Click); + // // Ribbon1 // this.Name = "Ribbon1"; @@ -214,6 +237,7 @@ private void InitializeComponent() internal Microsoft.Office.Tools.Ribbon.RibbonButton btn_SingData; internal Microsoft.Office.Tools.Ribbon.RibbonGroup grp_Finishing; internal Microsoft.Office.Tools.Ribbon.RibbonButton btn_AcceptFormatting; + internal Microsoft.Office.Tools.Ribbon.RibbonButton btn_WordFreq; } partial class ThisRibbonCollection diff --git a/EditTools/Ribbon1.cs b/EditTools/Ribbon1.cs index 1898ec9..d6e048c 100644 --- a/EditTools/Ribbon1.cs +++ b/EditTools/Ribbon1.cs @@ -554,5 +554,71 @@ private void btn_AcceptFormatting_Click(object sender, RibbonControlEventArgs e) view.ShowInsertionsAndDeletions = true; MessageBox.Show("Formatting changes have been accepted."); } + + private void btn_WordFreq_Click(object sender, RibbonControlEventArgs e) + { + Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument; + Dictionary wordlist = new Dictionary(); + Regex re_allnums = new Regex(@"^\d+$"); + + foreach (Word.Range rng in TextHelpers.GetText(doc)) + { + string txt = rng.Text; + + //strip punctuation + txt = TextHelpers.StripPunctuation(txt); + + + string[] substrs = Regex.Split(txt, @"\s+"); + foreach (string word in substrs) + { + Match m = re_allnums.Match(word); + if (!m.Success) + { + if (wordlist.ContainsKey(word)) { + wordlist[word]++; + } else + { + wordlist.Add(word, 1); + } + } + + } + } + + //Create new document + Word.Document newdoc = Globals.ThisAddIn.Application.Documents.Add(); + Word.Paragraph pgraph; + + //Intro text + pgraph = newdoc.Content.Paragraphs.Add(); + pgraph.set_Style(newdoc.Styles["Heading 1"]); + pgraph.Range.Text = "Word Frequency List\n"; + pgraph = newdoc.Content.Paragraphs.Add(); + pgraph.set_Style(newdoc.Styles["Normal"]); + pgraph.Range.Text = "Capitalization is retained as is. That means that words that appear at the beginning of a sentence will appear capitalized. Don't forget that you can sort the table!\n"; + + pgraph = newdoc.Content.Paragraphs.Add(); + pgraph.Range.InsertBreak(Word.WdBreakType.wdSectionBreakContinuous); + Word.Section sec = newdoc.Sections[2]; + sec.PageSetup.TextColumns.SetCount(3); + + var words = wordlist.ToList(); + words.Sort((pair1, pair2) => pair2.Value.CompareTo(pair1.Value)); + newdoc.Tables.Add(pgraph.Range, words.Count, 2); + int row = 1; + foreach (var pair in words) + { + Word.Cell cell = newdoc.Tables[1].Cell(row, 1); + cell.Range.Text = pair.Key; + cell = newdoc.Tables[1].Cell(row, 2); + cell.Range.Text = pair.Value.ToString(); + row++; + } + + pgraph = newdoc.Content.Paragraphs.Add(); + pgraph.Range.InsertBreak(Word.WdBreakType.wdSectionBreakContinuous); + newdoc.GrammarChecked = true; + } } } diff --git a/README.md b/README.md index 2bc41ed..b858af6 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,11 @@ These are just a couple tools I coded for use where I work. Features include a * one-click language applicator, -* one-click "accept formatting changes," -* proper noun discrepancy checker, +* "singular data" finder, * word list generator, -* "singular data" finder, and +* word frequency generator, +* proper noun discrepancy checker, +* one-click "accept formatting changes," and * comment boilerplate manager. The language applicator applies the language to *all* text, including notes, headers, and footers. Text boxes and frames may be skipped. I haven't done extensive testing around those. diff --git a/deploy/make-installer.iss b/deploy/make-installer.iss index cea06a4..f2ffac2 100644 --- a/deploy/make-installer.iss +++ b/deploy/make-installer.iss @@ -34,10 +34,10 @@ ; The version number. It is suggested to use the semantic versionin ; scheme (http://semver.org), but this is not a must. This version ; information may contain text. -#define SEMANTIC_VERSION "1.1.0" +#define SEMANTIC_VERSION "1.2.0" ; The version in four-number format -#define FOUR_NUMBER_VERSION "1.1.0.0" +#define FOUR_NUMBER_VERSION "1.2.0.0" ; The year(s) of publication (e.g., "2014-2017") #define PUB_YEARS "2017" diff --git a/screen-capture.jpg b/screen-capture.jpg index ea1571f2b618e4b14a169b6bbb33b3f41b62f436..2d3b4a65d70109d5188eae4c60ed0a4e39271401 100644 GIT binary patch delta 10481 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 delta 9279 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 OIWPYoy`1)b?tcJrwmmrj