Journo: /ˈdʒɜːnəʊ/ noun (plural journos)
- An informal word for journalist.
Journo is a Janet library for building interactive, interview-style CLI interfaces.
- Nicely formatted interactive question and answer interface
- Several basic question types (
:text
,:password
,:select
,:checkbox
) - Windows and Linux compatible
- Ability to customize styles with a
:style
keyword - Ability to validate user inputs by passing any predicate function via a
:validate
keyword - More question types
- Helper functions (at least, if not a fleshed-out API/DSL) for branching question paths based on previously-entered inputs
Using Journo is simple:
- First, define a Question (or list of questions).
- Then, pass a single question to
journo/ask
or list of questions tojourno/interview
.- These functions will present nicely formatted prompts to the user and return a table containing their response(s).
With JPM:
$ jpm install https://github.com/CFiggers/journo
In your project.janet
:
(declare-project
:name "your-project"
:dependencies ["https://github.com/CFiggers/journo"])
Optionally, run jpm deps
after adding the dependency to your project.janet
(not needed if you already installed via the instructions above).
In your main file:
(import journo)
# This will ask a single question and store the response in `answer`.
(def answer (journo/ask
{:question "What's your name?"
:type text}))
# This will ask all three questions and store the responses in `answer`.
(def answers (journo/interview
[{:label :q1
:question "What's the password?"
:password}
{:label :q2
:question "Favorite flavor?"
:type :select
:choices ["Vanilla" "Chocolate" "Strawberry"]}
{:label :q3
:question "Select all that apply"
:type :checkbox
:choices ["I'm overworked" "I'm underpaid"]}]))
To see a quick example in action, run the following command from the journo project root:
$ janet example/example.janet
Journo's API is very simple—it exposes two primary macros, each of which is a thin wrapper around a single function (which you're welcome to call directly if you like):
(journo/ask question &named keywordize)
Pass a single question to this function to have it asked at the command line.
The question must be a dictionary (table or struct) and contain :label
, :question
, and :type
. :type
can be one of:
:text
or "text" = Open input:password
or "password" = Open input, replaced with*
in terminal:select
or "select" = Single choice (provide with:choices
):checkbox
= Multiple choice (provide with:choices
)
Example:
(journo/ask {:label :q1 :question "Who?" :type :text})
Returns a single table containing :question
and ':answer'.
(journo/interview questions &named keywordize)
Pass an indexed datastructure of questions to this function to have each one asked in order at the command line.
Questions must be a dictionary (table or struct) and contain :label
, :question
, and type
. type
can be one of:
:text
or "text" = Open input:password
or "password" = Open input, replaced with*
in terminal:select
or "select" = Single choice (provide with:choices
):checkbox
= Multiple choice (provide with:choices
)
Example:
(journo/interview
[{:label :q1 :question "Who?" :type :text}
{:label :q2 :question "What?" :type :select
:choices ["Me" "Not me"]}])
Returns a table of user inputs as captured for each question.
(journo/interview* qs &named keywordize)
This is the function form of the journo/ask
and journo/interview
macros.
Pass either a question or an indexed datastructure of questions to this function to have each one asked in order at the command line.
Returns a table of user inputs captured for each question.
Comments, concerns, questions, issues, pull requests, code critiques, all are welcome.
The following libraries do this sort of thing way better and have been doing it for way longer:
- JavaScript
- Python
As far as I know, at time of writing there is nothing comparable to this library for Janet (happy to be corrected on that count though).
Enjoy!