Add xleb, charter, and dmesktop entries
Rosencrantz
6 years ago
| 1 |
_model: page
|
| 2 |
---
|
| 3 |
title: xleb
|
| 4 |
---
|
| 5 |
body:
|
| 6 |
|
| 7 |
The [xleb](https://github.com/aisamanra/xleb) library is a DSL for declaratively parsing XML structures. It uses a monadic structure to implicitly traverse the underlying XML structure, match on parts, and extract the relevant data.
|
| 8 |
|
| 9 |
Consider an XML format that looks like the following, with the `author` tags being considered optional:
|
| 10 |
|
| 11 |
```haskell
|
| 12 |
<feed>
|
| 13 |
<title>Feed Name</title>
|
| 14 |
<author>Pierre Menard</author>
|
| 15 |
<entry title="Entry 01">First Post</entry>
|
| 16 |
<entry title="Entry 02">Second Post Post</entry>
|
| 17 |
</feed>
|
| 18 |
```
|
| 19 |
|
| 20 |
A parser for this format using the `xleb` library might look like this:
|
| 21 |
|
| 22 |
```haskell
|
| 23 |
import Control.Applicative (optional)
|
| 24 |
import qualified Text.XML.Xleb as X
|
| 25 |
|
| 26 |
data Feed = Feed
|
| 27 |
{ feedTitle :: String
|
| 28 |
, feedAuthor :: Maybe String
|
| 29 |
, feedEntry :: [Entry]
|
| 30 |
} deriving (Eq, Show)
|
| 31 |
|
| 32 |
data Entry = Entry
|
| 33 |
{ entryTitle :: String
|
| 34 |
, entryContents :: String
|
| 35 |
} deriving (Eq, Show)
|
| 36 |
|
| 37 |
feed :: X.Xleb Feed
|
| 38 |
feed = X.elem "feed" $ do
|
| 39 |
feedTitle <- X.child (X.byTag "title") $ X.contents X.string
|
| 40 |
feedAuthor <- optional $ X.child (X.byTag "author") $ X.contents X.string
|
| 41 |
feedEntries <- X.children (X.byTag "entry") entry
|
| 42 |
return Feed { .. }
|
| 43 |
|
| 44 |
entry :: X.Xleb Entry
|
| 45 |
entry = Entry <$> X.attr "title" X.string <*> X.contents X.string
|
| 46 |
```
|
| 1 |
_model: page
|
| 2 |
---
|
| 3 |
title: Charter
|
| 4 |
---
|
| 5 |
body:
|
| 6 |
|
| 7 |
The [charter](https://github.com/aisamanra/charter) tool is a basic tool for Cabal-based project scaffolding. There are a number of tools that do this—Cabal comes with the `cabal init` command built-in, for example, and there's also the heavily configurable [`hi`](https://github.com/fujimura/hi) project—but none of them had quite what I wanted, so I built my own.
|
| 8 |
|
| 9 |
It has three main modes of operation, all of which will create a directory that contains a `cabal` file, initialize a git repo, and build out whatever other scaffolding is required. For basic executables, you can use
|
| 10 |
|
| 11 |
```
|
| 12 |
$ charter quick the-thing
|
| 13 |
```
|
| 14 |
|
| 15 |
and it will create `the-thing/the-thing.cabal` and `the-thing/src/Main.hs` for you, with a trivial entry point, and initialize a git repo with them. For a library, you can use a similar command, with optional `-m` flags to add new modules
|
| 16 |
|
| 17 |
```
|
| 18 |
$ charter library the-thing -m This -m That.TheOther
|
| 19 |
```
|
| 20 |
|
| 21 |
and in addition to `the-thing/the-thing.cabal`, it will also create the stubbed-out library modules `the-thing/src/This.hs` and `the-thing/src/That/TheOther.hs`. Finally, for larger executables (which I prefer to implement as a wrapper executable along with a library), you can use
|
| 22 |
|
| 23 |
```
|
| 24 |
$ charter executable the-thing
|
| 25 |
```
|
| 26 |
|
| 27 |
and in addition to `the-thing/the-thing.cabal`, it will also create the stubbed-out library code in `the-thing/src/TheThing.hs` as well as stubbed-out executable code in `the-thing/the-thing/Main.hs`.
|
| 28 |
|
| 29 |
All of these commands can also take other flags that fill in Cabal metadata: for example, `-l GPL` to specify a GPL license, `-d "some description"` to set the package description, `-a package-name` to add a dependency, and so forth. You can also add extra executable stanzas with `-b executable-name` and modules with `-m ModuleName`.
|
| 1 |
_model: page
|
| 2 |
---
|
| 3 |
title: dmesktop
|
| 4 |
---
|
| 5 |
body:
|
| 6 |
|
| 7 |
The [`dmesktop` program](https://github.com/aisamanra/dmesktop) is an application launcher for Linux based on `dmenu`, but using [XDG Desktop entries](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html) instead of exposing every binary in your `$PATH`. It is unfinished but usable, and can be installed with the following `cargo` command:
|
| 8 |
|
| 9 |
```
|
| 10 |
$ cargo install --git https://github.com/aisamanra/dmesktop.git
|
| 11 |
```
|
| 12 |
|
| 13 |
One mild frustration I had with the built-in `dmenu_run` launcher application is that it will allow you to uselessly launch non-graphical programs in a context where they will never be useful: running `sed` without arguments from a graphical context, for example. In contrast, `dmesktop` will only display applications which would also be offered by a desktop manager such as GNOME.
|
| 14 |
|
| 15 |
In my own usage, I have `dmenu_run` still bound and use it occasionally, but usually use `dmesktop` as my primary application launcher.
|
12 | 12 |
<nav class="menu">
|
13 | 13 |
<ul class="nav navbar-nav">
|
14 | 14 |
<li><a href="/">home</a></li>
|
15 | |
<li>projects</li>
|
| 15 |
<li>tools and programs</li>
|
16 | 16 |
<ul>
|
17 | 17 |
<li><a href="/projects/bricoleur">bricoleur</a></li>
|
| 18 |
<li><a href="/projects/charter">charter</a></li>
|
| 19 |
<li><a href="/projects/dmesktop">dmesktop</a></li>
|
18 | 20 |
<li><a href="/projects/matterhorn">matterhorn</a></li>
|
19 | 21 |
</ul>
|
20 | 22 |
<li>libraries</li>
|
|
23 | 25 |
<li><a href="/libraries/config-ini">config-ini</a></li>
|
24 | 26 |
<li><a href="/libraries/cube-cotillion">cube cotillion</a></li>
|
25 | 27 |
<li><a href="/libraries/telml">telml</a></li>
|
| 28 |
<li><a href="/libraries/xleb">xleb</a></li>
|
26 | 29 |
</ul>
|
27 | 30 |
<li>art & writing</li>
|
28 | 31 |
<ul>
|