8

I´m creating an application that converts text to Braille. Converting to Braille is not a problem, but I don´t know how to convert it back.

Example 1: Converting numbers to Braille

1     = #a
123   = #abc
12 45 = #ab #de

Example 2: Converting capitals to Braille

Jonas = ,jonas
JONAS = ,,jonas

I have a problem converting Braille back to normal. I can't just convert every a to 1 and so on. The numbers can be checked by the # and then change the chars after it to the next space, but I dont know how. The comma before the letter is harder to separate from other commas in the text.

Here is my class for converting to braille:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace BrailleConverter
{
    class convertingBraille
    {
        public Font getIndexBrailleFont()
        {
            return new Font("Index Braille Font", (float)28.5, FontStyle.Regular);
        }

        public Font getPrintableFontToEmbosser()
        {
            return new Font("Lucida Console", (float)28.5, FontStyle.Regular);
            //return new Font("Index Black Text Font", (float)28.5, FontStyle.Regular);
        }

        public string convertCapitalsToUnderscore(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return "";
            }

            text = " " + text;

            text = text.Replace('.', '\'');
            text = text.Replace(',', '1');
            text = text.Replace('?', '5');
            text = text.Replace('!', '6');
            text = text.Replace(':', '3');
            text = text.Replace('=', '7');
            text = text.Replace('+', '4');
            text = text.Replace('*', '9');
            text = text.Replace('é', '=');

            StringBuilder newText = new StringBuilder(text.Length * 2);
            newText.Append(text[0]);

            bool firstCapLetterInWord = true;

            for (int i = 1; i < text.Length; i++)
            {
                char letter = text[i]; // Aktuell bokstav
                char nextLetter = ' '; // Nästa bokstav

                try
                {
                    nextLetter = text[i + 1];
                }
                catch
                {

                }

                // Är det stor bokstav?
                if (char.IsUpper(letter))
                {
                    // Är nästa bokstav stor?
                    if (char.IsUpper(nextLetter))
                    {
                        // Är det början av ett helt ord med caps?
                        if (firstCapLetterInWord)
                        {
                            newText.Append(",,"); // 2 st understräck framför ordet

                            firstCapLetterInWord = false; // Ändra så att inte nästa bokstav får 2 st understräck
                        }
                    }
                    else // Annars bara ett understräck
                    {
                        if (firstCapLetterInWord)
                        {
                            newText.Append(","); // Sätt understräck framför bokstav
                        }

                        firstCapLetterInWord = true; // Förbereda för nästa capsord
                    }
                }

                newText.Append(text[i]);
            }

            string finishedText = newText.ToString().TrimStart(); // Ta bort mellanslaget i början

            finishedText = finishedText.ToLower();

            finishedText = finishedText.Replace('å', '*');
            finishedText = finishedText.Replace('ä', '>');
            finishedText = finishedText.Replace('ö', '[');

            return finishedText;
        }

        public string convertNumbersToBrailleNumbers(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return "";
            }

            text = " " + text;

            StringBuilder newText = new StringBuilder(text.Length * 2);
            newText.Append(text[0]);

            bool firstNumberInNumber = true;

            for (int i = 1; i < text.Length; i++)
            {
                char letter = text[i]; // Aktuell tecken
                char nextLetter = ' '; // Nästa tecken

                try
                {
                    nextLetter = text[i + 1];
                }
                catch
                {

                }

                char convertedChar = text[i];

                // Är tecknet en siffra?
                if (char.IsNumber(letter))
                {
                    // Är nästa tecken en siffra?
                    if (char.IsNumber(nextLetter))
                    {
                        // Är det början av ett flertaligt nummer?
                        if (firstNumberInNumber)
                        {
                            newText.Append('#'); // Brädkors framför nummret

                            firstNumberInNumber = false; // Ändra så att inte nästa siffra får brädkors
                        }
                    }
                    else // Annars bara ett understräck
                    {
                        if (firstNumberInNumber)
                        {
                            newText.Append('#'); // Sätt brädkors framför siffran

                        }

                        firstNumberInNumber = true; // Förbereda för nästa flertaliga nummer
                    }
                }

                newText.Append(convertedChar);
            }

            string finishedText = newText.ToString().TrimStart();

            finishedText = finishedText.Replace('1', 'a');
            finishedText = finishedText.Replace('2', 'b');
            finishedText = finishedText.Replace('3', 'c');
            finishedText = finishedText.Replace('4', 'd');
            finishedText = finishedText.Replace('5', 'e');
            finishedText = finishedText.Replace('6', 'f');
            finishedText = finishedText.Replace('7', 'g');
            finishedText = finishedText.Replace('8', 'h');
            finishedText = finishedText.Replace('9', 'i');
            finishedText = finishedText.Replace('0', 'j');

            return finishedText;
        }

        public string convertBackToPrint(string oldText)
        {
            string newText = oldText.Replace(",", "");
            newText = newText.Replace("#", "");
            newText = newText.Replace("*", "å");
            newText = newText.Replace(">", "ä");
            newText = newText.Replace("[", "ö");
            newText = newText.Replace('\'', '.');
            newText = newText.Replace('1', ',');
            newText = newText.Replace('5', '?');
            newText = newText.Replace('6', '!');
            newText = newText.Replace('3', ':');
            newText = newText.Replace('7', '=');
            newText = newText.Replace('4', '+');
            newText = newText.Replace('9', '*');
            newText = newText.Replace('=', 'é');

            return newText;
        }
    }
}
  • could you paste your sample code? and also an example with full statement not single word. – VIRA Sep 11 '12 at 07:36
  • 4
    Excuse my ignorance but, isn't Braille formed by raised dots on paper? – Jodrell Sep 11 '12 at 07:43
  • Maybe you should use something else instead of commas - some sequence of symbols, which can be rarely met in text: Jonas => @#%^jonas. Than you could make inverse operations easier – horgh Sep 11 '12 at 07:46
  • After fixing your formatting and spelling I still don't understand your question. – Jodrell Sep 11 '12 at 07:54
  • 1
    @Jodrell: In at least some kinds of Braille, the same symbols (dot combinations) are used for digits and for letters, but digits are prefixed by a number sign to indicate that a number is about to follow. That number prefix is expressed by `#` in the question. – O. R. Mapper Sep 11 '12 at 07:56
  • 2
    This is [Braille ASCII](http://en.wikipedia.org/wiki/Braille_ASCII) I assume? If so "other commas in the text" shouldn't exist, by my reading, they should have been converted into 1s. – Damien_The_Unbeliever Sep 11 '12 at 08:09
  • @Damien_The_Unbeliever, ahh, it all start to make sense. It probably makes more sense to convert to http://en.wikipedia.org/wiki/Braille_Unicode_block – Jodrell Sep 11 '12 at 08:16
  • @Jodrell: The OP will have to tell more about the goal of this operation for us to make such a judgement. When working with Braille, sometimes only 6 dots are available (e.g. on a destination device), and the exact inverse operation is a lesser concern. Also, language-specific abbreviations (for commonly-used character combinations) are sometimes used. – O. R. Mapper Sep 11 '12 at 08:20
  • So, this problem applies to all prefixes, not just the "number prefix", the other prefixes (especially the "uppercase prefix") would have to be handled to provide a more accurate conversion from Unicode or ASCII Braille. – Jodrell Sep 11 '12 at 08:25
  • @O.R.Mapper, I see, it makes sense for the meaning to vary by language. Presumably, for non Roman scripts there are less Braille Glyphs available for "shortcuts", i.e. with Greek or Cyrillic. Even with most Roman langauges, reserving `$` or `U+282B` for the "ed" suffix would be wasteful. – Jodrell Sep 11 '12 at 08:36
  • 2
    I have to convert to this chars so our brailleprinter will print it correctly. So I must use comma in front if a letter to make it a capital. It is converted for swedish braille table so I have other chars to convert to, like åäö. In my example above it is not looking right. One comma infron of a letter meens capital letter, and two commas meens that the whole word is capitals. – Jonas Löfkvist Sep 11 '12 at 09:20
  • You need to look into `RegEx`, I had a similar problem recently, and my solution was to read and replace character by character, after all this is the same thing `string.Replace()` does + `string.Replace` will be slower if you're replacing a lot of text. [See my question here](http://stackoverflow.com/questions/12334427/realtime-search-and-replace/12334849) – Chibueze Opata Sep 11 '12 at 09:51
  • @ChibuezeOpata yes I think so to, but I have never worked with RegEx, so this is a little bit overkill for me to solv :) – Jonas Löfkvist Sep 11 '12 at 10:59

2 Answers2

1

Thinking about this, perhaps, what you actually want to do is implement your own encoding, called somthing like PrintableSwedishBrailleAsciiEncoding inheriting from the Encoding base class.

using System.Text;

public sealed PrintableSwedishBrailleAsciiEncoding : Encoding
{
    ...
}

That would maximise the resuability of you code and enable you to simply use the rest of the framework to do your work.


In response to your comment on my now deleted answer, I think you are asking,

How can I replace a certain character, followed by any number of non whitespace chars, up until the first whitespace char. Or, more generally, whole words beginning with a certain character?

So you could use a Regex something like this, I think this would match a # followed by a number of non whitespace characters.

var numberMatcher = new Regex(@"#\w+")
var firstMatch = numberMatcher.Match(yourText)

var alteredMatch = SomeTextAlteringFunction(firstMatch);

var yourNewText = numberMatcher.Replace(yourText, alteredMatch);
Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • Yes that will be perfect when I reach that level of programing :) I know I can do alot to improve my convertingClass, and I will do that later. But just now I need to fix this quickly. My converting class is working fine, and I can print with no problem. My problem is to return the text to its orginal stat. – Jonas Löfkvist Sep 11 '12 at 10:33
  • Yes thats right. because I change every number to letters with # in front of it. ex 2012 will change to #bjab. And then I want to convert it back to numbers. – Jonas Löfkvist Sep 11 '12 at 10:46
  • 1
    @JonasLöfkvist, I think I've answered your specific question but in my edit but, if you implemented `Encoding` correctly it would allow you to convert back and forth between `Unicode` and your specialised encoding. – Jodrell Sep 11 '12 at 11:08
  • Thanks everyone! I do now know with direction to go with this :) – Jonas Löfkvist Sep 12 '12 at 05:44
0

This was my solution (Thanks alot Jodrell)

        public string convertBackToPrint(string oldText)
        {
            string newText = oldText.Replace(",", "");
            newText = newText.Replace("*", "å");
            newText = newText.Replace(">", "ä");
            newText = newText.Replace("[", "ö");
            newText = newText.Replace('\'', '.');
            newText = newText.Replace('1', ',');
            newText = newText.Replace('5', '?');
            newText = newText.Replace('6', '!');
            newText = newText.Replace('3', ':');
            newText = newText.Replace('7', '=');
            newText = newText.Replace('4', '+');
            newText = newText.Replace('9', '*');
            newText = newText.Replace('=', 'é');

            var numberMatcher = new Regex(@"#\w+");
            var firstMatch = numberMatcher.Match(newText);
            string alteredMatch = convertToNum(firstMatch.ToString());
            string yourNewText = numberMatcher.Replace(newText, alteredMatch);

            return yourNewText;
        }

        private string convertToNum(string oldText)
        {
            string newText = "";

            newText = oldText.Replace("a", "1");
            newText = newText.Replace("b", "2");
            newText = newText.Replace("c", "3");
            newText = newText.Replace("d", "4");
            newText = newText.Replace("e", "5");
            newText = newText.Replace("f", "6");
            newText = newText.Replace("g", "7");
            newText = newText.Replace("h", "8");
            newText = newText.Replace("i", "9");
            newText = newText.Replace("j", "0");
            newText = newText.Replace("#", "");

            return newText;
        }