Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?

Name Formatter

Description
This Script formats current clipboard text name with options for qoute style, delimiter and case. Current text and a preview of changed text is shown.
This uses Windows Form for multiple comboboxes in one dialog box, and also allows the user to tab between comboboxes, and the enter button, using solely the keyboard to interact or the mouse.
Qoute options include double, single, backtick and none.
Delimiter options include space, dot, comma, tab, newline, semicolon and none.
Case options include Title, Upper, Lower, Sentence, Meme
Language
C#.net
Minimum Version
Created By
Cory7929
Contributors
-
Date Created
Apr 5, 2023
Date Last Modified
Apr 5, 2023

Macro Code

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.ObjectModel;

// The 'text' parameter will contain the text from the:
//   - Current Clipboard when run by HotKey
//   - History Item when run from the History Menu
// The returned string will be:
//   - Placed directly on the Clipboard when run as a Macro
//   - Ignored by ClipboardFusion if it is 'null'
//   - Passed along to the next action in a Trigger (null changed to an empty string)
public static class ClipboardFusionHelper
{
    /// <summary>
    /// Enum <c>OutputWrapType</c> contains the different types of wraps that can be used.
    /// </summary>
    public enum OutputWrapType
    {
        Unqouted,
        QoutedDouble,
        QoutedSingle,
        QoutedBacktick,
        Parenthesis,
        MarkdownSpoiler,
        XML,
        RegexStartLine,
        RegexEndLine,
        RegexStartWord,
        RegexEndWord,
        RegexStartEndLine,
        RegexStartEndWord,
    }

    /// <summary>
    /// Dictionary <c>OutputWrapTypeDictionary</c> contains the values for the different types of wraps that can be used.
    /// </summary>
    public static readonly ReadOnlyDictionary<
        OutputWrapType,
        (string Start, string End)
    > OutputWrapTypeDictionary = new ReadOnlyDictionary<OutputWrapType, (string Start, string End)>(
        new Dictionary<OutputWrapType, (string Start, string End)>
        {
            { OutputWrapType.Unqouted, (Start: "", End: "") },
            { OutputWrapType.QoutedDouble, (Start: "\"", End: "\"") },
            { OutputWrapType.QoutedSingle, (Start: "'", End: "'") },
            { OutputWrapType.QoutedBacktick, (Start: "`", End: "`") },
            { OutputWrapType.Parenthesis, (Start: "(", End: ")") },
            { OutputWrapType.MarkdownSpoiler, (Start: ">! ", End: " !<") },
            { OutputWrapType.XML, (Start: "<", End: "/>") },
            { OutputWrapType.RegexStartLine, (Start: "^", End: "") },
            { OutputWrapType.RegexEndLine, (Start: "", End: "$") },
            { OutputWrapType.RegexStartWord, (Start: "\\b", End: "") },
            { OutputWrapType.RegexEndWord, (Start: "", End: "\\b") },
            { OutputWrapType.RegexStartEndLine, (Start: "^", End: "$") },
            { OutputWrapType.RegexStartEndWord, (Start: "\\b", End: "\\b") },
        }
    );

    /// <summary>
    /// Enum <c>OutputDelimiterType</c> contains the different types of delimiters that can be used.
    /// </summary>
    public enum OutputDelimiterType
    {
        Space,
        Dot,
        QuestionMark,
        Asterisk,
        DotAndAsterisk,
        Comma,
        Tab,
        NewLine,
        Semicolon,
        Colon,
        None,
    };

    /// <summary>
    /// Dictionary <c>OutputDelimiterTypeDictionary</c> contains the values for the different types of delimiters that can be used.
    /// </summary>
    public static readonly ReadOnlyDictionary<
        OutputDelimiterType,
        string
    > OutputDelimiterTypeDictionary = new ReadOnlyDictionary<OutputDelimiterType, string>(
        new Dictionary<OutputDelimiterType, string>
        {
            { OutputDelimiterType.Space, " " },
            { OutputDelimiterType.Dot, "." },
            { OutputDelimiterType.QuestionMark, "?" },
            { OutputDelimiterType.Asterisk, "*" },
            { OutputDelimiterType.DotAndAsterisk, ".*" },
            { OutputDelimiterType.Comma, "," },
            { OutputDelimiterType.Tab, "\t" },
            { OutputDelimiterType.NewLine, "\n" },
            { OutputDelimiterType.Semicolon, ";" },
            { OutputDelimiterType.Colon, ":" },
            { OutputDelimiterType.None, "" },
        }
    );

    /// <summary>
    /// Enum <c>OutputCaseType</c> contains the different types of cases that can be used.
    /// </summary>
    public enum OutputCaseType
    {
        /// <summary>The first letter of each word is capitalized, and the rest of the word is lower case.</summary>
        TitleCase,

        /// <summary>All letters are capitalized.</summary>
        UpperCase,

        /// <summary>All letters are lower case.</summary>
        LowerCase,

        /// <summary>The first letter of the first word is lower case, and the rest of the word is lower case.</summary>
        SentenceCase,

        /// <summary>Each word is randomly capitalized.</summary>
        MemeCase,

        /// <summary>No change to the case.</summary>
        None,
    };

    /// <summary>
    /// Method <c>ProcessText</c> Creates a window with comboboxes with options for each type of title setting to apply and a button to paste the text.
    /// </summary>
    ///
    public static string ProcessText(string text)
    {
        string input = text ?? BFS.Clipboard.GetText();
        string output = input;
        // Create window with comboboxes with options for each type and a button to paste

        // Create an array of the Types of Emnms to loop through
        Type[] types = new Type[]
        {
            typeof(OutputWrapType),
            typeof(OutputDelimiterType),
            typeof(OutputCaseType),
        };

        // Create a new form
        Form form = new Form();
        // Make the form size automatically fit the controls and be non-resizable
        form.AutoSize = true;
        form.AutoSizeMode = AutoSizeMode.GrowAndShrink;
        form.FormBorderStyle = FormBorderStyle.FixedDialog;
        // Set the form title
        form.Text = "Name Formater";
        // Set no Icon
        form.Icon = null;

        // Add TableLayoutPanel to the form to allow for the controls to be centered with 3 columns and 4 rows where
        // Row 1 is for comboboxes for the different types of title settings
        // Row 2 is for Paste button
        // Row 3 is for the current text
        // Row 4 is for the preview text
        TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
        // Set the number of columns
        tableLayoutPanel.ColumnCount = 3;
        // Set the number of rows
        tableLayoutPanel.RowCount = 4;
        // Make the form size automatically fit the controls and fill itself
        tableLayoutPanel.AutoSize = true;
        tableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
        tableLayoutPanel.Dock = DockStyle.Fill;
        // Add the TableLayoutPanel to the form
        form.Controls.Add(tableLayoutPanel);

        // Add the current text to the table layout panel on the first row and the first column
        Label currentLabel = new Label();
        currentLabel.Text = "Current Text:";
        tableLayoutPanel.Controls.Add(currentLabel, 0, 2);
        // Add the current text to the table layout panel on the first row and spanning the second and third column
        Label currentTextLabel = new Label();
        currentTextLabel.Text = input;
        currentTextLabel.AutoSize = true;
        currentTextLabel.Dock = DockStyle.Fill;
        tableLayoutPanel.Controls.Add(currentTextLabel, 1, 2);
        tableLayoutPanel.SetColumnSpan(currentTextLabel, 2);

        // Add the preview text to the table layout panel on the second row and the first column
        Label previewLabel = new Label();
        previewLabel.Text = "Preview Text:";
        tableLayoutPanel.Controls.Add(previewLabel, 0, 3);
        // Add the preview text to the table layout panel on the second row and spanning the second and third column
        Label previewTextLabel = new Label();
        previewTextLabel.Text = input;
        previewTextLabel.AutoSize = true;
        previewTextLabel.Dock = DockStyle.Fill;
        tableLayoutPanel.Controls.Add(previewTextLabel, 1, 3);
        tableLayoutPanel.SetColumnSpan(previewTextLabel, 2);

        // Add ComboBoxes to the table layout panel on the third row
        ComboBox[] comboBoxes = new ComboBox[types.Length];
        for (int i = 0; i < types.Length; i++)
        {
            // Create a new combobox
            ComboBox comboBox = new ComboBox();
            // Add items to the combobox from the enum values converted to strings
            comboBox.DataSource = Enum.GetValues(types[i]);
            // Stop the value from being changed
            comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
            // Set the combobox size to automatically be as wide as possible
            comboBox.AutoSize = true;
            comboBox.Dock = DockStyle.Fill;
            // Add the combobox to the array
            comboBoxes[i] = comboBox;
            // Add the combobox to the table layout panel on the first row and the current column
            tableLayoutPanel.Controls.Add(comboBox, i, 0);
            // Add evemt handler to the combobox to update the output text when the value is changed
            comboBox.SelectedIndexChanged += (sender, e) =>
            {
                ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);
            };
        }
        // Create a new button
        Button pasteButton = new Button();
        // Set the button size to automatically be as wide as possible
        pasteButton.AutoSize = true;
        pasteButton.AutoSizeMode = AutoSizeMode.GrowAndShrink;
        pasteButton.Dock = DockStyle.Fill;
        // Set the button text
        pasteButton.Text = "Paste";
        // Add dialog result to the button
        pasteButton.DialogResult = DialogResult.OK;
        // Make button the default button
        form.AcceptButton = pasteButton;
        // Add the button to the table layout panel on the second row and spanning all columns
        tableLayoutPanel.Controls.Add(pasteButton, 0, 2);
        tableLayoutPanel.SetColumnSpan(pasteButton, 3);
        // Set the form start position type to manual
        form.StartPosition = FormStartPosition.Manual;
        // Set the initial Location of the form to the current mouse position
        // (Divide dimmensions of form by 2 to center it on the cursor position)
        form.Location = new Point(
            Cursor.Position.X - (form.Width / 2),
            Cursor.Position.Y - (form.Height / 2)
        );
        // Ensure form is ontop of all other windows
        form.TopMost = true;
        // Refresh the form when the form is shown
        form.Shown += (sender, e) =>
        {
            ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);
        };

        // Show the form
        form.ShowDialog();
        if (form.DialogResult != DialogResult.OK)
        {
            return null;
        }
        ProcessOutput(ref output, ref previewTextLabel, input, comboBoxes);

        // Paste the output to the clipboard
        BFS.Clipboard.PasteText(output);
        // Return
        return output;
    }

    private static void ProcessOutput(
        ref string output,
        ref Label previewTextLabel,
        string input,
        ComboBox[] comboBoxes
    )
    {
        // Get the selected Enums from the comboboxes
        OutputWrapType wrapType = (OutputWrapType)comboBoxes[0].SelectedItem;
        OutputDelimiterType delimiterType = (OutputDelimiterType)comboBoxes[1].SelectedItem;
        OutputCaseType caseType = (OutputCaseType)comboBoxes[2].SelectedItem;
        // Split the input into an array of words using any non leter or number as a delimiter, and remove any empty strings
        string[] words = Regex
            .Split(input, "[^a-zA-Z0-9]")
            .Where(x => !string.IsNullOrEmpty(x))
            .ToArray();
        // Convert the words to the specified case
        ToCase(ref words, caseType);
        // Join the words with the specified delimiter and add the specified wrap types
        output =
            OutputWrapTypeDictionary[wrapType].Start
            + string.Join(OutputDelimiterTypeDictionary[delimiterType], words)
            + OutputWrapTypeDictionary[wrapType].End;
        // Set the preview text to the output
        previewTextLabel.Text = output;
    }

    /// <summary>
    /// Method <c>ToCase</c> converts the words in the array to the specified case as if they were a sentence.
    /// </summary>
    /// <param name="words">The array of words to convert.</param>
    /// <param name="caseType">The case to convert the words to.</param>
    private static void ToCase(ref string[] words, OutputCaseType caseType)
    {
        switch (caseType)
        {
            case OutputCaseType.TitleCase:
                words = words
                    .Select(x => x.Substring(0, 1).ToUpper() + x.Substring(1).ToLower())
                    .ToArray();
                break;
            case OutputCaseType.UpperCase:
                words = words.Select(x => x.ToUpper()).ToArray();
                break;
            case OutputCaseType.LowerCase:
                words = words.Select(x => x.ToLower()).ToArray();
                break;
            case OutputCaseType.SentenceCase:
                words = words.Select(x => x.ToLower()).ToArray();
                words[0] = words[0].Substring(0, 1).ToUpper() + words[0].Substring(1);
                break;
            case OutputCaseType.MemeCase:
                Random random = new Random();
                // For each letter in each word, randomly capitalize it
                words = words
                    .Select(
                        x =>
                            x.Select(
                                    y =>
                                        random.Next(0, 2) == 0
                                            ? y.ToString().ToUpper()
                                            : y.ToString().ToLower()
                                )
                                .Aggregate((a, b) => a + b)
                    )
                    .ToArray();
                break;
        }
    }
}