Journaling About Coding a Journal | Part 2

Part 1 is here.

One of the first things that struck me about how C# works is the fact that it wants everything to be in a class. I vaguely recall classes being a thing in C++, but it was something I never really messed around with.

The nice thing is that the way it handles namespaces and file inclusion makes a whole lot more sense.

First: no include directives! For core libraries, you can include a Using directive to shorten the typing, but like with C++, everything is still accessible by defining the scope at the time you're using it. This includes third-party libraries too (the complier uses a manifest file to know where everything is instead).

Namespace also feels a little more flexible to me, although I'm not sure it's actually that different from C++. What I really like, though, is that you can organize files without having to include them. As long as everything uses the same namespace, it's all accessible right off the bat.

The requirement to use classes for everything also really helps with organization; it forced me to divide things up anyway, so I may as well categorize the various functions I'm putting together.

Now in Technicolor

One of the things I decided early on was that I wasn't going to use any third-party libraries. I'd take a look at how other people had done things, but I wanted to do everything from scratch. I'll learn a lot more that way, and it's more fun to figure out a puzzle than simply apply a tool.

The first thing I wanted to do was style text output. Terminal apps are nothing but text (although I've seen some ways to change that...), so I want to get the most of it.

There's a built in ConsoleColor attribute (actually an enum), but that only works with Windows. Since I'm developing on Linux (and want it to be cross-platform anyway), I had to find something else. Meanwhile, most *nix-based consoles (plus MacOS') support a much greater color depth than Windows.

For the *Nix consoles, I was able to do some tinkering and found that they'll recognize ANSI escape codes. These are a specific sequence of characters where, if you output them to the console, they'll change the color and what-not. I originally had an issue with Konsole, KDE's default console, not recognizing them. I later discovered that this was actually a matter of the escape characters having to be capitalized. It really was that simple, and was something I discovered completely by accident.

So for my original implementation, I figured I'd just detect the OS, and then my color output function would actually style the text based on that. This was simple enough, and worked fine, even if I couldn't help but feel it was a little clunky, or at least inefficient.

I was looking up something else when, lo and behold, I found the escape character that the Windows terminal recognizes. The documentation is a little opaque, in that it spreads the information over a couple of pages, but it turned out to be the upper-case version of what I had been using for *Nix all along. No more duplicate code!

...Or so I thought. The problem is that Microsoft has a pathological aversion to following standards. In order to get the Windows console to use an escape sequence with colors, you have to use the SetConsoleMode function, which is part of the standard C library, but not C#. I could implement this directly in C# by loading a Windows DLL on runtime and then executing the code that way. There are also some third-party libraries that hook in at runtime to give this functionality. But in either case, I'd have to have OS-detecting code (since there's no need for the DLL on anything else). At that point I'm much better off just using the built-in color coding for Windows and escape sequences everywhere else.

The code is simple enough. I have a public class called Globals, which associates a number with some simple color names (and the number depends on the platform, i.e. Windows or something else). Then my color writing function has an if/else block to use the correct language for the OS. Honestly, from what I've seen my approach is smaller in terms of lines of code than any other implementation I've seen, all of which seem hell bent on over-complicating the whole thing.

I also have a couple of additional helper functions, to do things like bold and underlining (even if Windows doesn't support those at all), as well as center text on screen.

Finally, I've got some basic file saving logic, but I'm not getting too deep into this until I get the editor part working. After all, I won't know quite what a given “entry” is going to look like until much further down the road.

Next time, the beginnings of an editor, which causes a great deal of headache.

#coding #journalApp