Coder Social home page Coder Social logo

ltext / ltext Goto Github PK

View Code? Open in Web Editor NEW
36.0 3.0 5.0 6.78 MB

λtext - higher-order file applicator

License: BSD 3-Clause "New" or "Revised" License

Haskell 79.35% Nix 20.65%
haskell lambda-calculus delimiter expression-evaluator file-concatenation text-substitution

ltext's Introduction

ltext

λtext

General-Purpose Templating Utility

Overview

λtext turns text files into higher-order functions, featuring a Hindley-Milner / prenex polymorphic type system. See the github.io page.

Building

$> git clone [email protected]/ltext/ltext
$> cd ltext
$> stack install ltext

This should install in one pass; all the non-stackage dependencies are included in stack.yaml.

Using Nix

You can build with nix with the following command:

nix-build -A ltext.components.exes.ltext

Usage

$> ltext --help

λtext - parameterized file evaluator

Usage: ltext EXPRESSION [--version] [-t|--type] [-v|--verbose] [-r|--raw FILE]
             [--left LEFT] [--right RIGHT]
  Evaluate EXPRESSION and send the substitution to stdout. See
  http://ltext.github.io/ for more details.

Available options:
  -h,--help                Show this help text
  --version                Print the version number
  -t,--type                Perform type inference on an expression
  -v,--verbose             Be verbose, sending info through stderr
  -r,--raw FILE            Treat these files as plaintext without an arity
                           header
  --left LEFT              The left delimiter to use for rendering partially
                           applied files
  --right RIGHT            The right delimiter to use for rendering partially
                           applied files

$> ltext --type "\a -> a"

a0 -> a0

How It Works

From λtext's point of view, any text file can be a template (given that it's utf-8 encoded). Just declare parameters in the first line of your files (usually in a different syntax than the file's native tongue, via comments or obscure delimiters), then use those variables somewhere in the content. With the ltext command you can then apply the function-y files to each other.

The CLI

There will be two primary uses of the ltext command - evaluating template expressions, and querying for the type signature of a template/expression.

Type Queries

Just like the :t command in GHCi, you can find out the type of a template or expression with -t.

Expression Evaluation

All files have closed scope, meaning they only have access to the variables declared in the file. For instance:

{{ foo }}

...

Will only have access to the variable foo, while using the delimiters {{ and }} to escape your expression.

Variable Recognition

When we use a parameter in a file, we need it to be easily recognized by a parser; a different syntax than to the language you're working with.

The first line in a file will be parsed to see if it qualifies as a lambda header. If you don't want a file have recognized arity, just invoke ltext with the --raw argument listing the file:

$> ltext "foo bar" --raw "bar"

Credits

All credits go to Martin Grabmueller's AlgorithmW package for the type inference algorithm used in λtext.

ltext's People

Contributors

athanclark avatar waffle-iron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ltext's Issues

Isomorphic parsing / printing

Right now there's a shitty syntax being created internally for postponed expressions. It ain't right, it ain't tight.

Make YAML config more sensible

It's just duplicating command-line arguments right now, which isn't that great. It should also include global let terms, like flip, (.), et al. via string binding. Also, inclusion / merging should be ~/.ltext/config.yaml => ./.ltext/config,yaml.

Mapping

folders should be mappable, such that all files in the folder share the same type (no existential parameters), and that it's natively recursive. This introduces a new type atom Folder a, rather than Text, which gives the functor-like behavior.

Note that folders are naturally untyped, and allow for any set of types to reside in it, but only when we map do we expect ubiquity. This is useful, for instance, when applying GNU headers as comments or something:

comments.txt

{{ modulename }}
{-| Module: modulename
...
Copyright Foo (c) 2016
-}

bar.hs:

--{{ header }}--
--{{ header "Bar" }}--

module Bar where

-- the haskell code ...

Special syntax for raw text

It's inconvenient in some cases to have to edit a (potentially massive) file. It would be nice to declare a file as "raw" with a glob or some reserved character usually used in filesystems:

ltext "parameterizedIndex.html *dist/App.js *dist/style.css"

I don't really see a different character being possible other than *, even though this conflates meaning. Will need to ponder on this.

Weird sub-expression concatenation bug

For some reason, parsing a file to an expression, then beta reducing another parsed file is causing some weird contravariant concatenation in the sub expression. Figure out where this is coming from.

ltext-0.1.2.1 rebuild failed in Stackage Nightly

src/Main.hs:48:9: error:
    • Variable not in scope: (<>) :: Parser Bool -> Mod f11 a11 -> t
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
        ‘<*>’ (imported from Options.Applicative)

src/Main.hs:51:9: error:
    • Variable not in scope: (<>) :: Parser Bool -> Mod f9 a9 -> t5
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
        ‘<*>’ (imported from Options.Applicative)

src/Main.hs:52:9: error:
    • Variable not in scope: (<>) :: t5 -> Mod f10 a10 -> t
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
        ‘<*>’ (imported from Options.Applicative)

src/Main.hs:55:9: error:
    • Variable not in scope: (<>) :: Parser Bool -> Mod f7 a7 -> t4
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
        ‘<*>’ (imported from Options.Applicative)

src/Main.hs:56:9: error:
    • Variable not in scope: (<>) :: t4 -> Mod f8 a8 -> t
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
        ‘<*>’ (imported from Options.Applicative)

src/Main.hs:59:9: error:
    • Variable not in scope: (<>) :: Parser [String] -> Mod f4 a4 -> t3
    • Perhaps you meant one of these:
        ‘<=’ (imported from Prelude),
        ‘<$>’ (imported from Options.Applicative),
:

More Tests

Going to need a good testing framework:

  • Make Expr an instance of Arbitrary
  • idempotent typechecking & reduction
  • idempotent parsing & rendering

Earley parsing

Swap out the weird custom (Horrible) parser for a nice Earley expression. Shouldn't be too hard.

Better Lexer

Right now it's horrible - mixed state, and nasty accumulators. Turn it into multiple passes with pure functions.

Unexpected Behavoir

I am trying to use ltext to help me parameterise a number of shell scripts where I have to experiment with a bunch of values and options. However when I try to do this I seem to run into a number of issues:

  • If $$ value %% is preceded by text then no substitution occurs
  • If text follows $$ value %%, then on substitution the text is removed

Below are a few example cases:

Preceding text

The template file:

$ cat template

$$ value %%

This is broken

Nothing happens in this case $$ value %%

The file to be substituted

$ cat values

I am a value

Which when applied using ltext I get the following output

$ ltext "template values" --left "$$" --right "%%"

This is broken

Nothing happens in this case $$ value %%

Text following the parameter

The template file

$ cat template

$$ value %%

This is broken

$$ value %% now you see me

The file to be substitued

$ cat values

now you don't

When applied using ltext I get the following

$ ltext "template values" --left "$$" --right "%%"

This is broken

now you don't

I'm not sure if I'm missing something obvious or that that I should be doing someting different, but any help would be greatly appreciated

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.