FTD: Programming Language For Prose
FTD is an open source programming language for writing prose.
ftd Hello World!
-- import: lib

-- lib.h1: Hello World

Here is a FTD document that is importing a library, lib, and has a heading of level 1, “Hello World”. FTD language is designed for human beings, not just programmers, we have taken precautions like not requiring quoting for strings, not relying on indentation nor on braces that most programming languages require. It is not verbose like HTML, and not simplistic like Markdown.

FTD can be compared with Markdown, but in FTD you can do the following for example:

ftd.text kernel component
--- ftd.text: Hello World!
align: center
slot: right
$on-click$: toggle $current
padding: 20
text-align: center
color if $current: $fpm.color.main.cta-primary.base
color: $fpm.color.main.cta-primary.text
background-color: $fpm.color.main.text
Hello World!

We can define variables in FTD. FTD is strongly typed. We can do event handling. Since we are targetting “human beings” we have created a lot of “actions” that we believe one will be invoking on a day to day basis, like toggle, which can be used to create simple event handling.

You can also abstract out the logic in a custom ftd component, eg:

creating a custom component
-- ftd.text toggle-text: $title
boolean current: false
caption title:
$on-click$: toggle $current
text-align: center
color if $current: $fpm.color.main.cta-primary.base
color: $fpm.color.main.cta-primary.text
background-color: $fpm.color.main.text
padding: 20

-- toggle-text: FTD is cool!
FTD is cool!

Here we have created a new component called toggle-text, and then instantiated it instead. This way we can create custom component library and use them in our writing without “polluting” the prose with noise.

FTD is also a good first class data language. You can define and use records:

data modelling in ftd
-- record person:
caption name:
string location:
optional body bio:
Each field has a type. caption is an alias for string, and tells ftd that the value can come in the “caption” position, after the : of the “section line”, eg lines that start with -- or ---. If a field is optional, it must be marked as such.
creating a variable
-- person amitu: Amit Upadhyay
location: Bangalore, India

Amit is the founder and CEO of FifthTry.

He loves to code, and is pursuing his childhood goal of
becoming a professional starer of the trees.
Here we have defined a variable amitu. You can also define a list:
creating a list
-- person list employees:

-- employees: Sourabh Garg
location: Ranchi, India

-- employees: Arpita Jaiswal
location: Lucknow, India

Arpita is the primary author of FTD language.
We can then create a component that can render such record and loop over a list to show all members of the list:
looping over a list
-- render-person:
person: $p
$loop$: $employees as $p
This way we can have clean separation of data from presentation. The data defined in FTD documents can be easily read from say Rust:
reading data from ftd files
struct Employee {
    name: String,
    location: String,
    bio: Option<String>

let doc = ftd::p2::Document::from("some/id", source, lib)?;
let amitu: Employee = doc.get("amitu")?;
let employees: Vec<Employee> = doc.get("employees")?;

Data defined in FTD are first class data. Instead of sharing CSV/JSON files you can chose to share FTD files. Unlike CSV/JSON data in FTD are type checked. And unlike them you actually get a proper presentation of data, the FTD file can contain the definition of component that can render the data that you can view in your browser.

FTD can also be used as a configuration language.

FPM: FTD Package Manager
FTD has a sister project, fpm, a package manager for FTD.
Getting Involved

We are trying to create the language for human beings and we do not believe it would be possible without your support. We would love to hear from you.

Github: https://github.com/FifthTry/ftd

Discord: Join our ftd channel.

License: BSD

Checkout the Journal and Roadmap.

We have recorded some videos explaining FTD in detail for our internal team. You may benefit from them as well.