From 58619dd827249885f4d9f027802ee758146d24ae Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Tue, 8 Oct 2024 17:59:09 +0530 Subject: [PATCH] wip spec --- .github/workflows/deploy.yml | 15 ++ 01-overview.ftd | 149 ++++++++++++++++++++ 02-p1.ftd | 258 +++++++++++++++++++++++++++++++++++ README.md | 7 +- 4 files changed, 427 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/deploy.yml create mode 100644 01-overview.ftd create mode 100644 02-p1.ftd diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..7e15640 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,15 @@ +name: Deploy Site to FifthTry + +on: + push: + branches: + - main + +jobs: + build: + permissions: write-all + runs-on: ubuntu-latest + steps: + - name: actions/checkout@v4 + - run: sh -c "$(curl -fsSL https://fastn.com/install.sh)" + - run: fastn upload diff --git a/01-overview.ftd b/01-overview.ftd new file mode 100644 index 0000000..a88d92b --- /dev/null +++ b/01-overview.ftd @@ -0,0 +1,149 @@ +-- ds.page: `fastn` Specification + +This document describes the specification of the `fastn` language. It is not intended as +tutorial. + +This is not yet a formal document. It is a work in progress, and written in relatively plain +English. The goal is to make this an unambiguous document that can be used to implement `fastn`, +and any contribution is welcome. + +Currently there is only one implementation of `fastn`, but other alternate implementation are +welcome. + +-- ds.h1: Purpose Of The Language + +`fastn` language is a HTTP / User Interface language. A `fastn` program is a fullstack web +application. The HTTP part, and the User Interface, can be implemented in many ways. The +`fastn` compiler/runtime accepts a "path", eg `/hello/` as the entrypoint along with the +name of main `fastn`, and returns the JSON or User Interface. + +`fastn /` on terminal for example, when running from inside a folder containing a fastn +package will show terminal based user interface as described by our UI language. If +the author of the package wanted, `/` (or any path) can return a JSON, in which case +the output would be the JSON, and printed on terminal/piped into file. + +`fastn serve` can start a http server, and the request to the server from browser will +render the UI as described by the `fastn` language as a web page. If the author of the +fastn package want, they can return JSON, in which case the JSON will be returned to +browser with right content type. + +Instead of JSON authors can chose to return YML etc also, further, a UI also has backing +data, so instead of getting the UI, the client can do content negotiation, and request +the backing data as JSON or YML etc as well. + +-- ds.h1: Target + +`fastn` programs are invoked with a target. The target can be `stdio` for pure text output, +`terminal` for ncurses based terminal UI, `web` for Web Browsers, `windows`, `osx`, `linux`, +`ios`, `android` and so on. + +The way UI is rendered, and what UI capabilities are dependent on the target. A `fastn` +program can use `target` as a switch to provide different UI for different targets. + +`fastn` has a minimum ui abstraction, in the form of `ftd.*` components, that are available +on all supported `fastn` targets. Each target can also specify its own components, and +are only available on that target. + +-- ds.h2: Target Specific Libraries + +Target can also specify libraries that are available only on that target. There is a +target native way to define UI components, and library functions, that are available +when using that target. fastn ui components can use these target specific components, +and fastn user defined functions can call target specific functions. + +-- ds.h2: Target Neutral Vs Target Dependent Code + +When writing code, authors can write target neutral code, or target dependent code. +Most programs would use target neutral code, and only use target dependent code when +absolutely necessary. + + +-- ds.h1: Main `fastn` Package + +`fastn` code is organised as packages. There is a main package, which is the entrypoint of +the `fastn` program. The main package is the package that is invoked when the `fastn` program +is run. + +-- ds.h1: File Path Based Routing + +`fastn` programs take route, and other request input, as parameter. The `route` or `path` +is converted to a file path, and the file path is used to find the `fastn` module within +the fastn package. + +-- ds.h2: Dynamic Routes + +`fastn` package can have dynamic routes. The dynamic routes are specified in `FASTN.ftd` +file, and the dynamic routes are used to find the `fastn` module within the package. + +The dynamic routes can contain wildcards, and the wildcards are used to extract values +from the route, and these values are passed to the `fastn` module. + + +-- ds.h1: `fastn` Package + +`fastn` compiler works at package level. `fastn` files have an extension, `.ftd` and they are +organised into `fastn` packages. Each `fastn` package has a mandatory `FASTN.ftd` file at the +root level. + +A `fastn` package contains `ftd` files, and many other kind of files, JS files, CSS files, +PNG/JPEG, Font files and so on. + +A `fastn` package can be created to distribute static files as well, not just ftd files. + +-- ds.code: +lang: ftd + +\-- import: fastn +\-- fastn.package: hello-world + +-- ds.h1: `fastn` modules + +Any ftd file in a fastn package is a "fastn module". A fastn package is composed of zero or +more modules, and zero or more static files. + +fastn modules can also be created using `ftd.module` syntax: + +-- ds.code: +lang: ftd + +\-- ftd.module foo: ;; + +-- ds.h1: `p-script` + +The `fastn` files are composed of "sections", described in 02-p1 chapter. Each + + +-- ds.h1: Comments + +-- ds.h2: Line Comments + +`fastn` uses `;;` as line comment character. Everything from the first ``;;` till the end +of line is comment. Comments can be escaped by prefixing a backslash character: `\;;`. +Literal backslash can be inserted by putting two backslashes, `\\`. + + +-- ds.h2: Structural Comments + +Entire "section" can be commented out by adding a `/` in the front of the section, e.g., + +-- ds.code: +lang: ftd + +\/-- ftd.text: + +this is also commented out, because this is the body of the section, that started in +the line beginning with `--`, but it contains, `/--`, commenting out everything till +the next section or the end of file. + +\-- ftd.text: next section, not commented + +-- ds.markdown: + +In `0.4` we also allow `/` to comment out entire body, but we are deprecating that in +`0.5`. + +`/` can also be added in any of the section header, both simple and multi-line, to comment +out the entire header. + + +-- end: ds.page \ No newline at end of file diff --git a/02-p1.ftd b/02-p1.ftd new file mode 100644 index 0000000..1edae02 --- /dev/null +++ b/02-p1.ftd @@ -0,0 +1,258 @@ +-- ds.page: `ftd::p1` grammar + +`fastn` is based on a low-level grammar called `ftd::p1` grammar. + +-- ds.h1: `section` + +A `ftd::p1` file is composed of "sections". A section looks like this: + +-- ds.code: an `ftd::p1` file with two sections +lang: ftd + +\-- section-kind section: the caption of the section +header-kind header-1: some header value +hello: world + +the body of the first section + +\-- something: +yo: 42 + +-- ds.markdown: + +Each section starts with `-- `. + +The section has these properties: + +-- ds.h2: `section kind` + +The section kind can be define after `-- ` and before the section name. This is +optional parameter. + +In our case the `section-kind` is the section kind. + +Since section kind is optional, so a section can be defined with or without +section kind. + +-- ds.code: section with section kind +lang: ftd + +;; section kind in `string` +\-- string name: Some caption + +;; section kind is `string list` +\-- string list name: + + +-- ds.code: section without section kind +lang: ftd + +;; No section kind present +\-- my-section: + + + +-- ds.h2: `section name` + +The section name is the only **mandatory parameter** for a section. Name starts +after `-- ` or section kind if present, and ends with the first `:`. Trailing +`:` is mandatory. + +In our example, the name of the first section is `some section`, and the second +section's name is `something`. + +Section name contains alphanumeric characters, underscores, space, dots(`.`), +hash(`#`), and hyphens(`-`). Colon terminates the section name. + +Leading and trailing whitespaces are not considered part of the section name. + +-- ds.h2: `section caption` + +What comes after `:` in the section line, till the end of the first line is called +the `caption` of the section. + +The `caption` is optional. + +In our example, the first section's caption is "the caption of the section", and +the second section does not have a caption. + +Leading and trailing whitespaces are not considered part of the caption. + +-- ds.h2: `section headers` + +After the "section line" (the first line that starts with `-- `), zero or more +section headers can be passed. Header can be passed in two ways: `inline` and +`block` + +A section header consists of name (mandantory), kind (optional) and value +(optional). + +-- ds.h3: `inline header` + +In our example, the section has two headers, having names `header-1` and +`hello`, with values `some header value` and `world` respectively. Also the +first header `header-1` has kind `header-kind` + +An empty newline or the start of a new section marks the end of the headers. + +Leading and trailing whitespaces of both header name and header value are ignored. + +-- ds.code: `inline` header +lang: ftd + +\-- section-kind section: the caption of the section +header-kind header-1: some header value +hello: world + +-- ds.h3: `block header` - Deprecated + +We can also pass headers in block. This is commonly used when the value of +header is long and passing it in `inline` creates readability issue. + +-- ds.code: `block` header +lang: ftd + +\-- section-kind section-name: + +\-- section-name.block-header: + +Lorem ipsum dolor sit amet. Vel magni dolorum et doloremque nostrum aut dicta unde 33 quod quisquam sed ducimus placeat et placeat reiciendis ad nostrum rerum. Qui quasi eserunt ut aliquid galisum et harum porro et libero facilis cum corporis voluptatem est beatae minima non voluptatem maxime. Est quod ipsum sed neque labore ut tempora porro ut quae distinctio ad enim voluptatem ex praesentium molestiae. Ea iusto consectetur ab sequi voluptatem et inventore iste. + + +-- ds.markdown: + +The block header can be declared after `inline` header. It starts with `-- `, +follow by header kind, if present, then section name with `.` and after +this header name. Now, header value can be passed in caption or body area. + +In above example, the header name is `block-header` and has long value as `Lorem +ipsum dolor...` which is passed as body + +Header value can also take list of sections as value. And in that case, it needs +`end` statement to show the closing of header. + + +-- ds.code: `block` header +lang: ftd + +\-- section-kind section-name: + +\-- section-name.block-header: + +\-- some section: + +\-- another section: + +\-- end: section-name.block-header + +-- ds.h3: `end: header` + +-- ds.code: +lang: ftd + +\-- foo: +sidebar: + +\-- bar: + +end: sidebar +next-foo-header: 1 + + +-- ds.markdown: + +In this case the `sidebar` header to `foo` is a block header, and it ends at the +`end: sidebar` + +-- ds.h2: `section body` + +Like header, body can be passed in two ways: `inline` and `block` +The body is optional. + +Leading and trailing newlines are not considered part of the body. + +-- ds.h3: `inline` body + +After the first empty line that comes after the section header, till the start +of next section is considered the body of the section. + +-- ds.code: Section with inline body +lang: ftd + +\-- some section: + +This is body + + +\-- another section: +header: header value + +This is body + + +-- ds.h3: `block` body + +A section body can be passed as a `block`. This is particularly helpful in case +if the `block` headers are defined. In that case, the `body` can't be passed in +`inline`. + +-- ds.code: Section with block body +lang: ftd + +\-- some my-section: + +.... some block headers + +\-- my-section.my-body: + +This is body + + +-- ds.markdown: + +In above example, `my-body` is the body of section. + +Unlike `header`, `body` doesn't accept list of sections as value. + + + + + +-- ds.h1: `sub-section` + +A section can contain zero or more `sub-sections`: + +-- ds.code: +lang: ftd + +\-- some-section: + +\-- subsection1: yo yo + +\-- subsection2: + +subsection2 body + +\-- end: some-section + +-- ds.markdown: + +`subsections` are nothing but list of sections itself. If subsections are +defined, the section need to mark it's end using `end` keyword. + +In above example, `subsection1` and `subsection2` are two subsections for +`some-section` section. Also, the section is marked as end using `-- end: some-section` +statement. + +In above example, `some-section` section has two `sub-section`s, with names +`subsection1` and `subsection2` respectively. The first one has a caption, `yo yo`, +and the second one has a body, `subsection2 body`. + + +-- ds.h1: Programmatic Access + +`ftd::p11` module in `ftd` crate can be used to read `ftd.p1` files. Wrappers of +this crate in Python and other programming languages would hopefully come soon. + + +-- end: ds.page diff --git a/README.md b/README.md index 7535d1b..0be23b4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ -# spec -fastn language specification +# `fastn` language specification + +This repository contains the specification of work in progress, 0.5 version of fastn language. + +