Tuesday, July 16, 2024

EPUB format thoughts

 How hard can EPUB files be?

"EPUB is just HTML"! Hah!

I've got a fun EPUB ebook reader in the store; it's got two nifty features that, IMHO, all ebook readers should have (it can do an offline search of Project Gutenberg, and it's got a two-screen mode, so you can see both a critical image and the text that talks about the image in one spot).

Over the years, I've had to work around a lot of EPUB failures. Today's failure is thanks to the newer EPUB books that Project Gutenberg publishes.

Notably, each book seems to include a (pointless) <pre/> tag. The problem with that tag is that HTML does not support self-closing (void) elements. The Mozilla pages are super clear about that.

So my HTML renderer (which is just a WebView element) takes the <pre/> tag and reads it HTML style, like a <pre> tag that isn't closed. The entire rest of the book, which is most of it, is then displayed with pre-formatted lines. Because pre-formatted lines don't wrap (that's the point of the <pre> tag, the rest of the reading experience is mostly ruined.

SIGH. 


Wednesday, May 8, 2024

First thoughts on std::expected

 std::expected -- what can you do with it?

There's  a fancy new thing in C++: std::expected. There's a lot of pots about it's awesomeness, but what is it, really?


Answer: if you've got a std::expected, you can do three important things. Let's give a name to our std::expected: it's called result. And as a reminder: std::expected holds one of two values, which in this post I'll cleverly call "first" or "second".

1. Just result by itself is  a bool. When first is set, it returns true; when second is set, false.

2. *result is just first.

3. result.error() returns second.

You can also chain them together, assuming you have code where you want to do a bunch of stuff in order and will never have to refactor the code to be multi-threaded, or handle error conditions weirdly, or log something and then fail, or a lot of things. Oh, and using functions means lots of global variables, and the function must return a std::expected, not an int.

1. result.and_then(function) will call function with *result. The function can take exactly one variable, and the function will only be called if result was set to first.

2. result.or_else(function) is like the opposite of and_then. It's also a function that takes a single parameter (love them globals!) but take in the type of second, not first, and is only called if the second was set (the 'unexpected' branch).

Want to make a std::expected?

If you need to return a std::expected, and you're setting the first value, just return it and it's automatically cast into an object as needed. If you need to return the second value (unexpected), return a std::unexpected(). Be sure to not new it; just return std::unexpected("second value").


And some useless crap

What if you you've got a std::expected where first is an int, but you really need a double? Can you cast it? Nope, you can't. Casting is now called "transform".

There's a tranform_error(), too.

First thoughts: what about exceptions?

Lord knows. I guess exceptions aren't a thing any more?

What happens if I need to set a breakpoint? Answer: good luck with that. 

The source code the std::expected iat about 1500 lines of 

Sunday, April 14, 2024

XAML Style Dictionaries

Step by step: adding consistent styles to a XAML app

XAML has a useful feature where you can set up a single file with a bunh of "style" configuration for your XAML (UWP) app, and then use those styles everywhere in your app. The plus side is having a centralized style configuration: all your titles can be one size, and all your technical text has the correct font, and all. The downside is that getting it set up is buried in a blizzard of docs. There's a lot of ways to set up your XAML styles, and Microsoft wants you to fully understand each of them in isolation.

In this simple blog post, I walk through the steps of one way to add centralized styles to your app and then be able to use them everywhere.

Create an AppDictionary.xaml file. In your project, Add > New and add a XAML ResourceDictionary. Call is AppDictionary.xaml.

Add your first style. I tend to prefix all my centralized styles with a small "s" like "sTitle".

    <Style x:Key="sTitle" TargetType="TextBlock">
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="FontSize" Value="24" />
    </Style>    


Update every page and control to include the AppDictionary

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="AppDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>


Use the new style.  In a textblock, set the Style to be {StaticResource sTitle}.

        <TextBlock Style="{StaticResource sTitle}">Thingy Data</TextBlock>

Now you're styling with style, and it just took one short blog post to replaces multiple lengthy pages of explanation from the learn.microsoft.com site!