Posts tagged with "PyPI"

Rogallo v0.3.0

3 min read; 10 GFI

Rogallo

I've released Rogallo v0.3.0, which mostly concentrates on adding command line support and sorting support for browsing files in the local filesystem. There are also a couple of cosmetic configuration options thrown in.

Configurable cosmetics

Starting with the cosmetic configuration options: I got to feeling that the URI-containing tooltips that show on mouse-hover over a link might be a bit much for some people, so I've added show_link_tooltips to the configuration file1. Set it to false to make the tooltips go away.

Similar to this I've also added disable_animations. Out of the box Textual loves its animations. This is arguably most noticeable if you have a long body of text in a scrolling widget (such as the document viewer in Rogallo), as you use PgUp, PgDn, Home, End, etc., it'll scroll in a fancy animated way. It looks cool for a moment but I can imagine plenty of people getting sick of it, or feeling sick because of it (I sense this is an a11y issue too). With this in mind if disable_animations is set to true they'll all be turned off.

Command line options

Rogallo now also has a number of command line options that can come in useful. In part borrowing from a number of my other TUI applications, and also adding some specific to Rogallo itself. They can be easily found with the --help switch:

usage: rogallo [-h] [-v] [-t THEME] {directories,dirs,d,license,licence,bindings,themes,open} ...

A terminal-based client for the Gemini Protocol.

positional arguments:
  {directories,dirs,d,license,licence,bindings,themes,open}
                        Available commands
    directories (dirs, d)
                        Show the directories created and used by Rogallo
    license (licence)   Show license information
    bindings            List commands that can have their bindings changed
    themes              List the available themes that can be used with --theme
    open                Open a location

options:
  -h, --help            show this help message and exit
  -v, --version         Show version information
  -t, --theme THEME     Set the theme for the application (see `themes` command for available themes)

v0.3.0

directories

Because I feel it's important that people know where applications drop things in your filesystem, there is the directories command, which shows you which directories are used by Rogallo.

$ rogallo directories
/Users/davep/.config/rogallo
/Users/davep/.local/share/rogallo

licence

On the off chance you really need to know the licence of Rogallo (it's GPL3+), you can ask to see the key details:

$ rogallo licence
Rogallo - A client for the Gemini protocol for the terminal.
Copyright (C) 2026 Dave Pearson

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.

bindings

If you wish to know what commands are available for binding, and what the default bindings are, you can use this command:

$ rogallo bindings
Backward - Move backward through history
    Default: ctrl+left_square_bracket
ChangeCommandLineLocation - Swap the position of the command line between top and bottom
    Default: ctrl+up, ctrl+down
ChangeTheme - Change the application's theme
    Default: f9
Forward - Move forward through history
    Default: ctrl+right_square_bracket
Help - Show help for and information about the application
    Default: f1, ?
JumpToCommandLine - Jump to the command line
    Default: /, ctrl+1
JumpToDocument - Jump to the document
    Default: ctrl+slash, ctrl+g, ctrl+2
Quit - Quit the application
    Default: f10, ctrl+q
ToggleHistory - Toggle the display of the history viewer
    Default: f2, ctrl+3

The how of changing bindings still needs to be documented, but it's the same as with most of my other TUI applications, so if you look at how it's done in OldNews, for example, you should get the idea.

themes

This lists the available themes that can be used with the --theme switch.

$ rogallo themes
atom-one-dark
atom-one-light
catppuccin-frappe
catppuccin-latte
catppuccin-macchiato
catppuccin-mocha
dracula
flexoki
gruvbox
monokai
nord
rose-pine
rose-pine-dawn
rose-pine-moon
solarized-dark
solarized-light
textual-dark
textual-light
tokyo-night

open

This command can be used to open a location from the command line. You can pass it either a URI for a Gemini capsule, or the path to a file in the local filesystem.

Viewing local files

Talking of viewing files in the local filesystem... that's now supported too. This is something I wanted to build in from the start, as I feel it could be handy to anyone writing gemtext files prior to deployment. I sense there might be a couple of edge cases relating to this that I might still need to iron out, but mostly it seems to be working well.

At some point I'll probably also pull in textual-fspicker so that the user can browse for files to view, making it just a little easier to open a file in some cases.

Not requiring the gemini:// scheme prefix

So far, to connect to a Gemini capsule, it's been necessary to provide the full URI. That's kind of annoying. It had been deliberately left like this until I sorted the work to allow specifying local files, as I wasn't quite sure how it would all interact. Now that I've got that in place I could address this too. So whereas before you had to type gemini://davep.gemcities.com/ to get to my test capsule, now it's enough to enter davep.gemcities.com.

There is some guesswork going on in the background, with the resolution rules looking something like this:

  • Have I been given a URI that is obviously a Gemini URI?
  • If not, if it has no scheme, and it matches the name of a file in the filesystem, let's assume the user meant that.
  • If it's not a file in the filesystem, and it doesn't have a scheme, let's slap gemini:// on the front and see how we get on with that.
  • None of the above applied, yet it has a scheme: throw it at the operating system's URI resolution system.

In casual testing so far this is working out well.

More to come

I'm still having a blast working on this, and there's still a lot more to do. The TODO list is staying pretty constant in size at the moment because, as I knock an item off, I seem to keep finding new things I want to add or improve. I see this as a good thing.

I have a very busy AFK life for the next week or so, so I don't imagine too many updates during that period. Once things have settled again I want to try and tackle the two big issues of user input and client certificates. I'll be happy that Rogallo is getting close to generally usable when I know I can log in and water my plant in Astrobotany.


  1. ~/.config/rogallo/configuration.json on most systems. This and all the options within will eventually be documented, when I get round to creating the site to document Rogallo. 

Rogallo v0.2.0

1 min read; 10 GFI

Rogallo v0.2.0 is now available. This version fixes some issues with links, makes gemtext parsing better conform with the specification, and also makes it easier to see where a link will take you.

The first issue is a fix to how page-relative links were resolved if the page you were viewing was the result of a redirection. What was happening was the links were being resolved relative to the initial URI, rather than the final URI of the redirection. This was most noticeably a problem when following links in the geminispace equivalent of webrings. The main change took place in Wasat, with Rogallo making use of the new Response.uri property.

The second fix was to how I parse gemtext. The initial parser was close enough, but I noticed there were some finer points relating to whitespace that I hadn't paid attention to (mainly due to skim-reading the specification). For example, I expected links to always start with => followed by a space, when in fact a link can simply start with a => and then be followed by the URI with no space.

link-line = "=>" *WSP URI-reference [1*WSP 1*(SP / VCHAR)] *WSP CRLF

Similar improvements to the detection of headings and quotes have also been added.

Finally, I've added a couple of features which make it easy to know where a link will take you. The first is that I've added a tooltip to each link, so that when you hover the mouse cursor over it the URI will be displayed. But, because not everyone is mouse-oriented in the terminal1, I've also added a status bar to the main viewer panel that shows the URI of the focused link.

The Rogallo status bar

As you tab through the links it will update, of course.

Status bar in action

This should ensure that links are less likely to be surprising.

If any of this sounds interesting and you want to have a play, Rogallo is licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed, you should be able to get up and running with:

pipx install rogallo

It can also be installed using uv:

uv tool install rogallo

If you don't have uv installed, you can use uvx.sh to perform the installation. For GNU/Linux, macOS, or similar:

curl -LsSf uvx.sh/rogallo/install.sh | sh

or on Windows:

powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/rogallo/install.ps1 | iex"

Once installed, run the rogallo command.


  1. Quite right too. 

Rogallo v0.1.0

1 min read; 12 GFI

I've just made public, and published to PyPI, v0.1.0 of Rogallo. As mentioned a couple of times recently, it's a terminal-based client for the Gemini Protocol.

Rogallo displaying the Gemini home page

This is a very early release, with lots of things still to be added. Right now it's at a place where it interacts with the basics of the protocol, handles the document format, and has the basic navigation facilities you'd expect from a document browser. Things I aim to add over the next few weeks include, in no specific order:

  • A bookmark facility
  • Support for the protocol's user input facility (status 1x)
  • Support for the protocol's client authentication facility (status 6x)
  • Support for local browsing (I want to be able to view and navigate local gmi files)
  • A settable home page
  • The ability to clear down the location history
  • A cache system

I'll also be updating the TODO list as other ideas come to mind.

Another thing fairly high on the list is documentation. For now, Rogallo should be pretty easy to grasp, and there is a help screen that describes all the keyboard bindings in the current context.

The help screen

Commands that can be run can also be discovered via the command palette.

The command palette

For those who care about different looks, there is, of course, support for loading up different themes.

The theme options

This means that even folk who, for some reason, like light themes, can go light too.

Rose pine theme Latte theme

Not really my thing, but I'm told some people like this.

If any of this sounds interesting and you want to have a play, Rogallo is licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed, you should be able to get up and running with:

pipx install rogallo

It can also be installed using uv:

uv tool install rogallo

If you don't have uv installed, you can use uvx.sh to perform the installation. For GNU/Linux, macOS, or similar:

curl -LsSf uvx.sh/rogallo/install.sh | sh

or on Windows:

powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/rogallo/install.ps1 | iex"

Once installed, run the rogallo command.

As I say above, this is very early days for the project, so don't be surprised if you find something missing, or even run into a bug or two. If you need help, have any ideas, or find any problems, please feel free to raise an issue or start a discussion.

Trouble with PyPI

2 min read; 7 GFI

I had quite the adventure with PyPI this morning, and I don't think it's over yet. It started out with the release of BlogMore v2.43.0. I did my usual thing of doing a test release to the test version of PyPI, and then did a production release.

As normally happens, I then went on to tag the release on GitHub, followed by writing the blog post to announce the new version. While doing this, despite the fact that it wasn't necessary given the nature of the change, I decided to update BlogMore in my blog's repository. That's when things started to look odd.

I did the usual make update but nothing new appeared. Now, it's not unheard of that I do this and no new version of BlogMore appears. Often I do it a couple more times and it's fine. So I kept trying every minute or two and still nothing. So I checked back on PyPI. Sure enough, a search showed that it had updated:

PyPI search

(The 16 minutes being about the time since I'd made the release), but when I clicked through it was showing the last version from a couple of days ago. Even when I looked at the release history it was saying the latest version was the previous version:

The apparent latest release

Odd.

At this point, depending on how I searched and where I went, I'd either see that my latest upload wasn't available, or I'd get a 500 error.

PyPI 500 error

Clicking through to the status page showed no errors. Clicking through to the Twitter account that was suggested showed nothing at all.

PyPI status on Twitter

Leaving aside the whole issue of having an account on Twitter these days anyway, I felt it wasn't that useful to point people at a resource that seems to have never been updated, so I did raise an issue about that.

Digging around the status page at some point, despite the fact that the main display was green all the way, I did see a rise in "PyPI CDN Edge Errors". I'm not a web guy, I'm not an infrastructure guy, so I'm not really sure what this would mean, but it sounds like it's not a good thing.

CDN edge errors

Opening the graph to look longer term, it did seem today was a spike, with another spike quite some time ago.

More CDN edge errors

At this point I left it a while, not announcing the new version of BlogMore. I came back some time later and, finally, I could see 2.43.0 was showing! Also, this seemed to coincide with the above graph calming down again.

A calm CDN

Seeing this I went to upgrade BlogMore in my blog's repo/venv and this time it all worked.

Yay!

At that point I left it alone and went about my work day. However, I don't think whatever is going on is over. Despite the fact that it was showing BlogMore as being v2.43.0 earlier today, once things were settled, I just checked again as I started to write this and:

Old BlogMore again

The search index on PyPI shows it as having been updated about 8 hours ago (as I write this), but the page itself shows that the latest version is from 2 days ago. At least installing it gives me 2.43.0:

$ uv add blogmore
Using CPython 3.13.1
Creating virtual environment at: .venv
Resolved 17 packages in 325ms
Installed 16 packages in 41ms
 + blogmore==2.43.0
 + feedgen==1.0.0
 + jinja2==3.1.6
 + lxml==6.1.1
 + markdown==3.10.2
 + markupsafe==3.0.3
 + minify-html==0.18.1
 + pillow==12.2.0
 + pygments==2.20.0
 + python-dateutil==2.9.0.post0
 + python-frontmatter==1.3.0
 + pyyaml==6.0.3
 + rcssmin==1.2.2
 + rjsmin==1.2.5
 + six==1.17.0
 + watchdog==6.0.0

Also: PISpy sees 2.43.0 as the latest version too (something it wasn't seeing during the height of the issues this morning).

It's all kind of confusing though.

Guess it's time for me to read up on CDN edge errors or something...

BlogMore v2.43.0

1 min read; 12 GFI

After recently adding Mermaid and maths support to BlogMore, I got to thinking that it now has connections with a handful of third-party resources. While almost all of them are optional (only FontAwesome comes close to being a hard requirement), it does mean that there are resources the user doesn't directly supply or control, and for which the URLs are hard-coded in the source for BlogMore.

I wasn't keen on this. While it's my intention to keep an eye on things and, periodically, check on those libraries and see if they need an update, I felt it was important that the user could override them on their own, without waiting on me.

So v2.43.0 adds a third_party section to the configuration file to give full control over these resources. The full version of it looks like this:

third_party:
  mermaid:
    script_url: "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"
  katex:
    css_url: "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css"
    js_url: "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"
  mathjax:
    js_url: "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
  fontawesome:
    metadata_url: "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/6.7.2/metadata/icons.json"
    webfonts_base: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/webfonts"
    css_url: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
    woff2_url: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/webfonts/fa-brands-400.woff2"
  force_graph:
    js_url: "https://unpkg.com/force-graph"

Of course, it's not an all-or-nothing setting; you can just set one of the values. So if you wanted to override the force_graph value it's enough to do:

third_party:
  force_graph:
    js_url: "https://unpkg.com/force-graph"

Hopefully this adds some useful flexibility. As well as giving the option to use a different version of a resource, it also allows you to host your own copy and refer to that instead. Heck, it would even allow totally replacing a library with a different one that has the same API, should you ever find yourself in that situation.

BlogMore v2.42.0

1 min read; 10 GFI

I've released BlogMore v2.42.0. This version is all about changes to the dump command.

When I first added it it simply dumped all of the data available about posts within a blog, meaning it was possible to do all sorts of things with the data outside of BlogMore itself. Having done this, and used the result to good effect (and also having seen at least one person also make use of it), I got to thinking that I should probably expose some other data that's going to be helpful.

Given that blogmore.el needs to dive into things like available categories and tags, and given that I'd also like to add support there for the recently-added series support, I realised that dumping those values as JSON would also be helpful.

So this release extends the dump command, adding a set of sub-commands:

  • posts: dumps the data about all posts in the blog (this is the default if you just run blogmore dump, so keeping the command backward-compatible).
  • categories: dumps all categories as slug/title pairs.
  • tags: dumps all tags as slug/title pairs.
  • series: dumps all series as slug/title pairs.

For example, getting all categories from this blog:

blogmore dump categories
[
  ["ai", "AI"],
  ["coding", "Coding"],
  ["creative", "Creative"],
  ["emacs", "Emacs"],
  ["gaming", "Gaming"],
  ["life", "Life"],
  ["meta", "Meta"],
  ["music", "Music"],
  ["python", "Python"],
  ["tech", "Tech"],
  ["til", "TIL"]
]

Or all the available series right now:

blogmore dump series
[
  ["agentic-afterthoughts", "Agentic Afterthoughts"],
  ["buying-the-steam-controller", "Buying the Steam Controller"],
  ["edinburgh-fringe-2023", "Edinburgh Fringe 2023"],
  ["reading-2bit-files-for-fun", "Reading 2bit files (for fun)"],
  ["swift-til", "Swift TIL"],
  ["the-great-github-copilot-meltdown-of-2026", "The Great GitHub Copilot Meltdown of 2026"],
  ["the-virgin-east-coast-saga", "The Virgin East Coast Saga"],
  ["emacs-d", "~/.emacs.d"]
]

While this data could have been gathered from the content of the dump of posts, this approach makes it far easier to work with and more accessible; simply put, it means there's less work for the user to do if they just want all the tags (for example). With this, and with a little bit of caching in the code (because this does require parsing all the posts every time), I think it will make for a better approach to category, tag and (when I add it) series completion while writing a post.

BlogMore v2.41.0

2 min read; 12 GFI

It's probably bad news if I have a Saturday afternoon and evening spare, a fully-charged laptop and a comfy sofa. It seems that when that happens, something like BlogMore v2.41.0 happens. This is a release where I've added two features that could be generally useful, but which I'm unlikely to use in my own blogs.

The first, which to be fair is one I might use (I've used it in documentation plenty of times over the years), is optional Mermaid support. This is off by default, so has no overhead if you don't turn it on. It is turned on by setting with_mermaid to true. Even with this enabled, the Mermaid third-party scripts only get included on pages that include a Mermaid diagram, reducing the overhead.

To include a Mermaid diagram you use a fenced codeblock with mermaid as the language identifier. For example:

```mermaid
graph TD
    A[Start] --> B[Process]
    B --> C{Decision}
    C -->|Yes| D[Success]
    C -->|No| E[Fail]
```

If Mermaid is enabled the resulting page will show this:

Example Mermaid diagram

There are, of course, all sorts of diagrams that can be used and I'm not going to go into them here, or in the BlogMore docs; Mermaid is well known enough and well-documented enough that anyone turning this on is likely to know what they're doing, or where to go to find out what to do.

The second new feature, which I am almost certainly never going to need to use on my blog, is LaTeX-style maths support. As with Mermaid, this is off by default and has no overhead if not used. Even when turned on with the with_maths setting, the external scripts will only be pulled into pages that include maths markup.

Two providers of rendering engines are supported and this can be configured with the maths_provider setting. The available options are katex (which is also the default) and mathjax.

To use either, when turned on, you use the usual $ or $$ convention for LaTeX-maths-in-Markdown:

You can make some fun images using:

$$
z_{n+1} = z_n^2 + c
$$

We can say $z_{n+1} = z_n^2 + c$ inline too.

The result of the above will be something like:

Maths markup in action

Note that some care has been taken to ensure that ordinary use of a $, in currency values for example, is left unaffected. This can't be guaranteed in every possible case, so keep this in mind when turning on with_maths. From what I have read this is a common issue when using such markup.

Both these features were fun to add, with me planning out the implementation with Antigravity, and having a back and forth a couple of times to address issues and get it all working "just so". I'm especially pleased with the fact that it's done in a way where there is no overhead, even when either feature is enabled, if a page isn't showing a diagram or maths markup.

BlogMore v2.40.0

2 min read; 12 GFI

I've just released BlogMore v2.40.0. This version contains just one new feature: post series support.

It's hardly a novel feature, plenty of blog engines support this sort of thing; I felt it was high time I added it to BlogMore too. The idea is simple: while categories provide a method of having "sub-blogs" within a blog (they also provide their own feeds), and while tags let you group together posts that touch on related subjects, a series will let you stitch together a collection of posts as directly relating to each other.

Adding a post to a series is as simple as adding a series to the frontmatter of a post.

title: Five days with Copilot
category: AI
tags: Python, AI, LLM, Copilot, GitHub, BlogMore, coding
date: 2026-02-20 15:46:00 +0000
series: Agentic Afterthoughts

With this done, when a reader is viewing an individual post that is within a series, some new navigation appears at the top and bottom of the post that lets them know about the series, and also offers them easy navigation to the previous and next posts.

Series navigation

Also, if the reader were to click on the series title, it will take them to an archive page for that series, where the posts are presented in the usual pagination format, but where they're also presented in series order. To be clear: series order is always chronological order.

To help encourage further post discovery, if one or more series are available, a new Series link appears at the top of the blog. This links to an index of every series available.

My blog's series index

Sorted in alphabetical order, the list also shows how many posts are in each series and, if reading time is turned on, the total reading time will be shown.

Worth noting is the fact that a post doesn't have to be restricted to just one series. If you need a post to be in two or more series, you can provide the series as a list:

title: My post that crosses the streams
category: Testing
tags: BlogMore, Series, Test
date: 2022-02-22 22:22:22 +2200
series:
  - Experiments with blogging
  - Eating my own dog food
  - Testing thing

The post will then show navigation for every one of those series, and the post will be in each series' archive page.

Having added this, I've also updated the output of the dump command so that series (the series list as provided in the frontmatter), safe_series (the series list in their URL-friendly slug forms) and series_pair (a list of series title and slug pairs) properties are available.

As of the time of writing this, I have noticed one issue. The linter isn't currently aware of the URLs that are created as part of the series facility. So if you have a page or post that links to the index, or links to a particular series, there will be errors:

blogmore lint
Linting site in content...
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/ (resolved to /series/)
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/ (resolved to /series/)
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/the-virgin-east-coast-saga/ (resolved to /series/the-virgin-east-coast-saga/)
Linting complete: 377 post(s), 4 page(s), 3 error(s), 0 warning(s) [0.45s].

This should be a straightforward fix which I'll make in a follow-up release.

BlogMore v2.39.0

1 min read; 13 GFI

BlogMore v2.39.0 has a couple of changes, one more or less cosmetic, the other a new feature that I probably should have added right near the start of the project.

First, the cosmetic: in pages and posts, when you use headings (#, ##, etc.), a is added to the end of each heading, along with some show-on-mouse-hover styling, to make it easy to grab the anchor of a particular section of a page1. A problem I'd noticed with this recently is that the shows up in the search text, and also in the content of all the feeds. While not a problem as such, it felt untidy.

So, with this release that particular character is stripped from the search index and from the feeds.

The second change is a facility that should be useful if you have legacy URLs that you really must have land on an actual page or post: redirection support.

This facility is provided by a new redirect_from frontmatter property. From now on, a page or a post can declare which URLs should be redirected to it. So, if you have a post that, given your current post location setup, would land at /2006/06/06/hello-world/, but in some other incarnation of your blog lived at /posts/2006-06-06-hello-world.html, you can now set this in the frontmatter:

redirect_from: /posts/2006-06-06-hello-world.html

and the old URL will be redirected to the new one. This is achieved by simply creating a very minimal HTML file at the old location, which contains a redirection. The content of the file will end up looking something like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Redirecting...</title>
    <link rel="canonical" href="https://example.com/2006/06/06/hello-world/">
    <meta http-equiv="refresh" content="0; url=/2006/06/06/hello-world/">
  </head>
  <body>
    <p>Redirecting to <a href="/2006/06/06/hello-world/">/2006/06/06/hello-world/</a>...</p>
  </body>
</html>

If a blog has migrated between locations and/or generation tools over the years, and there are a number of different legacy URLs out there still pointing to a post you really want to keep readable to all, you can also redirect from multiple URLs:

redirect_from:
  - /posts/2006-06-06-hello-world.html
  - /posts/2006/06/06/hello-world.html
  - /my/really/old/blog/structure/hello-world-06-06-06.html

While all of this would have been possible anyway, by creating the appropriate file, with the appropriate content, in the extras directory, this approach helps automate the process and also means that the redirection information lives with the page or post being redirected to.


  1. The recently-added floating ToC is another way to do this now too.