From filter to reader... again

This commit is contained in:
perro tuerto 2023-03-09 18:13:01 -08:00
parent bade83d6c1
commit 0ba2e10fc6
10 changed files with 6362 additions and 3044 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "opt/luaminify"]
path = opt/luaminify
url = https://github.com/stravant/LuaMinify.git

View File

@ -2,7 +2,7 @@
[Pandoc] is a world famous "swiss-army" document converted. This is because
Pandoc is also a document parser. Thanks to this capability, this repo is a
[Pandoc filter] written in [Lua] for [literate] and [natural] programming
[Pandoc reader] written in [Lua] for [literate] and [natural] programming
(LNP), i.e.: "[Programming \[...\] as the process of creating works of
literature][1]".
@ -13,18 +13,18 @@ literature][1]".
## Install
1. Go to [Releases].
2. Download the latest version of `literate.min.lua`.
2. Download the latest version of `literate.lua`.
3. Done!
## Usage
With `literate.min.lua` downloaded and Pandoc installed, do:
With `literate.lua` downloaded and Pandoc installed, do:
pandoc --lua-filter PATH/TO/literate.min.lua -t FORMAT DOC
pandoc -f PATH/TO/literate.lua -t FORMAT DOC
For example, if `DOC` is `source.md` and the output `FORMAT` is HTML, do:
pandoc --lua-filter PATH/TO/literate.min.lua -t html source.md
pandoc -f PATH/TO/literate.lua -t html source.md
## Manual
@ -69,7 +69,7 @@ Literate Pandoc is under [GPLv3].
Happy hacking :)
[Pandoc]: https://pandoc.org/
[Pandoc filter]: https://pandoc.org/lua-filters.html
[Pandoc reader]: https://pandoc.org/custom-readers.html
[Lua]: https://www.lua.org/
[literate]: https://en.wikipedia.org/wiki/Literate_programming
[natural]: https://en.wikipedia.org/wiki/Natural-language_programming

6312
dist/literate.lua vendored Normal file

File diff suppressed because one or more lines are too long

2957
dist/literate.min.lua vendored

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
Subproject commit cce8f5b51bdffd1e0439956ccc308d0e5d164f90

View File

@ -2,12 +2,10 @@
# Variables
NAME="fennel-1.3.0"
ROOT=$(git rev-parse --show-toplevel)
URL="https://fennel-lang.org/downloads/$NAME.tar.gz"
# Copies Fennel from release tarball
cd $ROOT/opt
curl -O $URL
tar -xvzf $NAME.tar.gz
mv $NAME/fennel.lua .
mv $NAME/fennel.lua opt/
rm -rf $NAME*

View File

@ -1,12 +1,11 @@
# Makes distribution release
# Variables
NAME="literate.min.lua"
ROOT=$(git rev-parse --show-toplevel)
DIST=$ROOT/dist/$NAME
NAME="literate.lua"
DIST=dist/$NAME
LICENSE="--[[
Literate Pandoc & Fennel Bundle:
A Pandoc filter for literate and natural programming
A Pandoc reader for literate and natural programming
Fennel:
(C) 2016-2023 Calvin Rose and contributors
License: MIT License https://git.sr.ht/~technomancy/fennel/tree/main/item/LICENSE
@ -20,15 +19,7 @@ The following code is minified, check Literate Pandoc source for a readable vers
]]--"
# Merges Fennel and Literate Pandoc
head -n -1 $ROOT/opt/fennel.lua > $DIST
(echo "$LICENSE") > $DIST
head -n -1 opt/fennel.lua >> $DIST
echo "local fennel = mod" >> $DIST
tail -n +11 $ROOT/src/literate.lua >> $DIST
echo "Bundling complete"
# Minifies code
cd opt/luaminify
lua CommandLineMinify.lua $DIST $DIST.tmp
# Adds license
(echo "$LICENSE" && cat $DIST.tmp) > $DIST
rm $DIST.tmp
tail -n +10 src/literate.lua >> $DIST

View File

@ -1,24 +1,20 @@
# Makes tests
# Variables
ROOT=$(git rev-parse --show-toplevel)
FILTER=$ROOT/src/literate.lua
NAME=literate.lua
READER=src/$NAME
ARGS=()
# Removes unwanted args
for arg in "$@"; do
case $arg in
"--dist") FILTER=$ROOT/dist/literate.min.lua ;;
"--dist") READER=dist/$NAME ;;
*) ARGS+=($arg) ;;
esac
done
# Moves to tests directory and clears the terminal
cd $ROOT/tests
clear
# Checks args
if [ -z "$*" ]; then
if [ -z "$ARGS" ]; then
echo "ERROR: At least one argument is needed. For example:"
echo " sh $0 native"
echo " sh $0 native markdown"
@ -29,8 +25,8 @@ fi
echo "🐾 Starting tests"
for arg in "$ARGS"; do
echo && echo "⚗️ Test in '$arg' format:"
mds=$'\n\n'`(pandoc -t markdown *.md)`
rst=$'\n\n'`(pandoc -t markdown *.rst)`
org=$'\n\n'`(pandoc -t markdown *.org)`
echo "$mds" "$rst" "$org" | pandoc --lua-filter $FILTER -t $arg
mds=$'\n\n'`(pandoc -t markdown tests/*.md)`
rst=$'\n\n'`(pandoc -t markdown tests/*.rst)`
org=$'\n\n'`(pandoc -t markdown tests/*.org)`
echo "$mds" "$rst" "$org" | pandoc -f $READER -t $arg
done

View File

@ -1,14 +1,13 @@
-- IMPORTANT: for distribution the first 10 lines are changed to:
-- local fennel = mod
-- Initial setup for development:
-- Enables Fennel for Lisp-Lua embeded compatibility
-- Cfr. https://fennel-lang.org
-------------------------------------------------------------------------------
-- IMPORTANT: these lines are changed to "local fennel = mod"
-- IMPORTANT: these line are for development setup
-- Enables Fennel <https://fennel-lang.org> for Lisp-Lua compatibility
local src_root = pandoc.path.directory(PANDOC_SCRIPT_FILE)
local fennel_lua = pandoc.path.join({src_root, "../opt/fennel.lua"})
package.path = package.path .. ";" .. fennel_lua
local fennel = require("fennel")
-- IMPORTANT: code for distribution starts after this line.
--[[
-------------------------------------------------------------------------------
-- Lua LPeg shortcuts
local P, S, R, Cf, Cc, Ct, V, Cs, Cg, Cb, B, C, Cmt =
lpeg.P, lpeg.S, lpeg.R, lpeg.Cf, lpeg.Cc, lpeg.Ct, lpeg.V,
@ -20,49 +19,42 @@ local lbracket = P"("
local rbracket = P")"
local word = (1 - (space + lbracket + rbracket))
-- Grammar for Pandoc parser that converts:
-- Lisp expression => pandoc.Plain
-- Lisp list => pandoc.Span
-- Lisp atom => pandoc.Str
-- Grammar
G = P{
"Doc";
Doc = space^0 * Ct(V"SExpr"^0) * space^0 / pandoc.Pandoc;
SExpr = (V"List" + V"Atom");
List = lbracket * V"SExpr"^0 * rbracket / embed;
List = lbracket * V"SExpr"^0 * rbracket;
Atom = space + V"Word";
Word = word^1 / pandoc.Str;
}
]]--
-- Evals Lisp code
-- @param code string: code to evaluate
-- @return table: evaluation result as {bool, string, string, string}
local function eval(code)
is_passed, out = pcall (
local is_passed, out = pcall (
function () return fennel.eval(code) end,
function (e) return e end
)
lua = ""
out = tostring(out)
preview = out:gsub("\n.*", "")
local lua = ""
local out = tostring(out)
local preview = out:gsub("\n.*", "")
if is_passed then
lua = fennel.compileString(code)
end
return {is_passed = is_passed, preview = preview, out = out, lua = lua}
end
return {
{
CodeBlock = function (block)
if block.classes:includes("eval") then
local raw = block.text
print("⚙️ ", raw)
local res = eval(raw)
print("", res["is_passed"], "", res["preview"])
if block.classes:includes("replace") then
return pandoc.CodeBlock(res["out"], {code=raw})
end
end
end,
}
}
-- Calls Pandoc Reader.
function Reader(input, options)
--[[
local doc = lpeg.match(G, tostring(input))
if options.standalone then
return exec(doc)
else
return doc
end
]]--
return pandoc.Pandoc(tostring(input))
end

View File

@ -7,7 +7,7 @@ Valid declarations:
* A declaration: f1() = (+ 1 2 3). All declarations should be print on `--verbose`.
* f2() = (+ 4 5 6) is another declaration.
* f3() = (+ 7 8 9)
* Two declarations: f4() = (- 9 8) and f5() = (- 7 6).
* Two declarations, one in inline code: f4() = (- 9 8) and `f5() = (- 7 6)`.
* Two consecutive declarations: f6() = (- 5 4) f7() = (- 3 2).
* A declaration with one arg: f8(n) = (* #n #n).
* A declaration with two args: f9(a, b) = (* #a #b).
@ -26,11 +26,6 @@ Not declarations:
* f19 = (+ 1 2); misses `()`
* f20() = + 1 2; misses `()`
* f21() (+ 1 2); misses `=`
* `f22() = (+ 1 2)`; inside inline code
```
f23() = (+ 1 2) inside code block
```
Overrides `f1()` with warn: f1() = (+ 2 3 4) and it should fail on `--fail-if-warnings`.
@ -41,11 +36,11 @@ Valid calls:
* A common call: f1(). All calls should be print on `--verbose`.
* f2() another common call.
* f3()
* Two calls: f4() and f5().
* Two calls, one in inline code: f4() and `f5()`.
* Two consecutive calls: f6() f7().
* A call with one arg: f8(2).
* A call with two args: f9(2, 3).
* A call with variable number of args: f10("The popular ", "\"Hello,", " ", "", "World!\"").
* A call with variable number of args: f10("The popular ", "\"Hello, ", "World!\"").
* A call with args as kwargs: f8(n: 3) and f9(a: 4, b: 5).
Valid calls and data types:
@ -71,11 +66,6 @@ Not calls:
* f19(1 2); misses comma separator
* f20( ); extra space
* f21({); incomplete data type
* `f22()`; inside inline code
```
f23() inside code block
```
Invalid calls:
@ -127,7 +117,7 @@ Valid recursion:
Invalid recursion:
* f26(i) = (* f11() i); \f11() not declared.
* f26(i) = (* f11() i); `f11()` not declared.
* f27(j) = (* f27(1) f27(2)); infinite loop.
* f8(n: f11()); \f11() not declared.
* f8(n: f11()); `f11()` not declared.
* f8(f8(3)); infinite loop.