gdritter repos infinite-negative-utility / 394fd49
Add xleb, charter, and dmesktop entries Rosencrantz 5 years ago
4 changed file(s) with 94 addition(s) and 1 deletion(s). Collapse all Expand all
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.
1212 <nav class="menu">
1313 <ul class="nav navbar-nav">
1414 <li><a href="/">home</a></li>
15 <li>projects</li>
15 <li>tools and programs</li>
1616 <ul>
1717 <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>
1820 <li><a href="/projects/matterhorn">matterhorn</a></li>
1921 </ul>
2022 <li>libraries</li>
2325 <li><a href="/libraries/config-ini">config-ini</a></li>
2426 <li><a href="/libraries/cube-cotillion">cube cotillion</a></li>
2527 <li><a href="/libraries/telml">telml</a></li>
28 <li><a href="/libraries/xleb">xleb</a></li>
2629 </ul>
2730 <li>art & writing</li>
2831 <ul>