Only generate lua manual docs; move tic80/love2d to other repo.
https://git.sr.ht/~technomancy/fennel-ls-docsets
This commit is contained in:
parent
aaf30a99be
commit
670f7d108b
25
Makefile
25
Makefile
@ -32,21 +32,20 @@ install: $(EXE)
|
|||||||
|
|
||||||
## Generating docs
|
## Generating docs
|
||||||
|
|
||||||
docs:
|
docs: src/fennel-ls/docs/generated/lua51.fnl \
|
||||||
$(FENNEL) $(FENNELFLAGS) tools/get-docs.fnl $(GET_DOCS_FLAGS)
|
src/fennel-ls/docs/generated/lua52.fnl \
|
||||||
|
src/fennel-ls/docs/generated/lua53.fnl \
|
||||||
|
src/fennel-ls/docs/generated/lua54.fnl
|
||||||
|
|
||||||
XDG_DATA_HOME ?= $(HOME)/.local/share
|
src/fennel-ls/docs/generated/%.fnl:
|
||||||
DOCSET_DIR = $(XDG_DATA_HOME)/fennel-ls/docsets/
|
mkdir -p build/
|
||||||
|
mkdir -p src/fennel-ls/docs/generated/
|
||||||
|
$(FENNEL) $(FENNELFLAGS) tools/generate-lua-docs.fnl ${*} > $@
|
||||||
|
|
||||||
$(DOCSET_DIR)/love2d.lua: src/fennel-ls/docs/generated/love2d.fnl
|
docs-love2d:
|
||||||
mkdir -p $(DOCSET_DIR)
|
@echo "This has moved to a separate source. Please see the wiki:"
|
||||||
$(FENNEL) $(FENNELFLAGS) --compile $< > $@
|
@echo "https://wiki.fennel-lang.org/LanguageServer"
|
||||||
|
@exit 1
|
||||||
src/fennel-ls/docs/generated/love2d.fnl:
|
|
||||||
$(FENNEL) $(FENNELFLAGS) tools/get-docs.fnl --generate-love2d
|
|
||||||
|
|
||||||
# has to be separate for licensing reasons
|
|
||||||
docs-love2d: $(DOCSET_DIR)/love2d.lua
|
|
||||||
|
|
||||||
rm-docs:
|
rm-docs:
|
||||||
rm -rf src/fennel-ls/docs/
|
rm -rf src/fennel-ls/docs/
|
||||||
|
|||||||
@ -9,6 +9,9 @@ Provides intelligent editing features for fennel files.
|
|||||||
* [Packaging](docs/packaging.md)
|
* [Packaging](docs/packaging.md)
|
||||||
* [Writing your own lint](docs/linting.md)
|
* [Writing your own lint](docs/linting.md)
|
||||||
|
|
||||||
|
For information about installing documentation data for 3rd-party libraries
|
||||||
|
like love2d or tic80 [see the wiki](https://wiki.fennel-lang.org/LanguageServer).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
fennel-ls is licensed under the MIT license. See LICENSE for more info.
|
fennel-ls is licensed under the MIT license. See LICENSE for more info.
|
||||||
This repository also contains files from other projects:
|
This repository also contains files from other projects:
|
||||||
|
|||||||
4
TODO.md
4
TODO.md
@ -119,9 +119,9 @@ done, but these are the sort of enhancements I am thinking about.
|
|||||||
- [ ] external docsets
|
- [ ] external docsets
|
||||||
- [X] load external docsets from ~/.local/share/fennel-ls/docsets/
|
- [X] load external docsets from ~/.local/share/fennel-ls/docsets/
|
||||||
- [X] warn on missing docset
|
- [X] warn on missing docset
|
||||||
- [ ] document how to download external docsets
|
- [X] document how to download external docsets
|
||||||
- [ ] document how to create external docsets
|
- [ ] document how to create external docsets
|
||||||
- [ ] move love2d and tic80 to external docsets (published .... where?)
|
- [X] move love2d and tic80 to external docsets (published .... where?)
|
||||||
- [ ] automatic downloading of external docsets
|
- [ ] automatic downloading of external docsets
|
||||||
- [ ] some kind of registry built-in?
|
- [ ] some kind of registry built-in?
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,9 @@
|
|||||||
## UNRELEASED / ???
|
## UNRELEASED / ???
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* Support loading external docsets from disk.
|
||||||
|
* Extract TIC-80 docs to external docset.
|
||||||
* Support `:lua-version` settings like `"lua5.4"` rather than requiring `"lua54"`.
|
* Support `:lua-version` settings like `"lua5.4"` rather than requiring `"lua54"`.
|
||||||
* Support `"union"` in `:lua-version` for globals present in any Lua version.
|
* Support `"union"` in `:lua-version` for globals present in any Lua version.
|
||||||
* Support `"intersection"` in `:lua-version` for globals present in every Lua version.
|
* Support `"intersection"` in `:lua-version` for globals present in every Lua version.
|
||||||
|
|||||||
@ -45,10 +45,7 @@
|
|||||||
(collect [k v (pairs lua-versions.lua51)]
|
(collect [k v (pairs lua-versions.lua51)]
|
||||||
(if (. lua-versions.lua54 k) (values k v))))
|
(if (. lua-versions.lua54 k) (values k v))))
|
||||||
|
|
||||||
(local libraries {:tic80 (require :fennel-ls.docs.generated.tic80)})
|
(local libraries {})
|
||||||
|
|
||||||
;; alias
|
|
||||||
(set libraries.tic-80 libraries.tic80)
|
|
||||||
|
|
||||||
(λ load-library [name]
|
(λ load-library [name]
|
||||||
(let [path (.. data-dir name docset-ext)]
|
(let [path (.. data-dir name docset-ext)]
|
||||||
@ -57,8 +54,9 @@
|
|||||||
(f:close)
|
(f:close)
|
||||||
(docs))
|
(docs))
|
||||||
_ {:status :not-found
|
_ {:status :not-found
|
||||||
:msg (string.format "Could not find docset for library %s at %s"
|
:msg (string.format "Could not find docset for library %s at %s\nSee %s"
|
||||||
name path)})))
|
name path
|
||||||
|
"https://wiki.fennel-lang.org/LanguageServer")})))
|
||||||
|
|
||||||
(λ get-library [name]
|
(λ get-library [name]
|
||||||
(when (not (. libraries name))
|
(when (not (. libraries name))
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://www.lua.org/manual/5.1/manual.html
|
;; auto-generated by `make docs` from fennel-ls. Contents come from
|
||||||
|
;; https://www.lua.org/manual/5.1/manual.html
|
||||||
;; Lua Lua 5.1 Reference Manual last updated Thu Aug 29 20:43:58 UTC 2019
|
;; Lua Lua 5.1 Reference Manual last updated Thu Aug 29 20:43:58 UTC 2019
|
||||||
(local docs {:_G {:binding "_G"
|
(local docs {:_G {:binding "_G"
|
||||||
:metadata {:fls/itemKind "Variable"
|
:metadata {:fls/itemKind "Variable"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://www.lua.org/manual/5.2/manual.html
|
;; auto-generated by `make docs` from fennel-ls. Contents come from
|
||||||
|
;; https://www.lua.org/manual/5.2/manual.html
|
||||||
;; Lua Lua 5.2 Reference Manual last updated Thu Aug 29 20:10:02 UTC 2019
|
;; Lua Lua 5.2 Reference Manual last updated Thu Aug 29 20:10:02 UTC 2019
|
||||||
(local docs {:_G {:binding "_G"
|
(local docs {:_G {:binding "_G"
|
||||||
:metadata {:fls/itemKind "Variable"
|
:metadata {:fls/itemKind "Variable"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://www.lua.org/manual/5.3/manual.html
|
;; auto-generated by `make docs` from fennel-ls. Contents come from
|
||||||
|
;; https://www.lua.org/manual/5.3/manual.html
|
||||||
;; Lua Lua 5.3 Reference Manual last updated Tue Jul 14 10:32:39 UTC 2020
|
;; Lua Lua 5.3 Reference Manual last updated Tue Jul 14 10:32:39 UTC 2020
|
||||||
(local docs {:_G {:binding "_G"
|
(local docs {:_G {:binding "_G"
|
||||||
:metadata {:fls/itemKind "Variable"
|
:metadata {:fls/itemKind "Variable"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://www.lua.org/manual/5.4/manual.html
|
;; auto-generated by `make docs` from fennel-ls. Contents come from
|
||||||
|
;; https://www.lua.org/manual/5.4/manual.html
|
||||||
;; Lua Lua 5.4 Reference Manual last updated Thu Jun 13 22:15:52 UTC 2024
|
;; Lua Lua 5.4 Reference Manual last updated Thu Jun 13 22:15:52 UTC 2024
|
||||||
(local docs {:_G {:binding "_G"
|
(local docs {:_G {:binding "_G"
|
||||||
:metadata {:fls/itemKind "Variable"
|
:metadata {:fls/itemKind "Variable"
|
||||||
|
|||||||
@ -1,418 +0,0 @@
|
|||||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://tic80.com/learn
|
|
||||||
{:BDR {:binding "BDR"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["row"]
|
|
||||||
:fnl/docstring "Allows you to execute code between the drawing of each fullscreen scanline, for example, to manipulate the palette.
|
|
||||||
"}}
|
|
||||||
:BOOT {:binding "BOOT"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/docstring "Startup function.
|
|
||||||
"}}
|
|
||||||
:MENU {:binding "MENU"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["index"]
|
|
||||||
:fnl/docstring "Game Menu handler.
|
|
||||||
"}}
|
|
||||||
:SCN {:binding "SCN"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["row"]
|
|
||||||
:fnl/docstring "Allows you to execute code between the drawing of each scanline, for example, to manipulate the palette.
|
|
||||||
"}}
|
|
||||||
:TIC {:binding "TIC"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "Main function. It's called at 60fps (60 times every second).
|
|
||||||
"}}
|
|
||||||
:btn {:binding "btn"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["id"]
|
|
||||||
:fnl/docstring "This function allows you to read the status of one of the buttons attached to TIC.
|
|
||||||
The function returns true if the key with the supplied id is currently in the pressed state.
|
|
||||||
It remains true for as long as the key is held down.
|
|
||||||
If you want to test if a key was just pressed, use `btnp()` instead.
|
|
||||||
"}}
|
|
||||||
:btnp {:binding "btnp"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["id" "?hold" "?period"]
|
|
||||||
:fnl/docstring "This function allows you to read the status of one of TIC's buttons.
|
|
||||||
It returns true only if the key has been pressed since the last frame.
|
|
||||||
You can also use the optional hold and period parameters which allow you to check if a button is being held down.
|
|
||||||
After the time specified by hold has elapsed, btnp will return true each time period is passed if the key is still down.
|
|
||||||
For example, to re-examine the state of button `0` after 2 seconds and continue to check its state every 1/10th of a second, you would use btnp(0, 120, 6).
|
|
||||||
Since time is expressed in ticks and TIC runs at 60 frames per second, we use the value of 120 to wait 2 seconds and 6 ticks (ie 60/10) as the interval for re-checking.
|
|
||||||
"}}
|
|
||||||
:circ {:binding "circ"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "radius" "color"]
|
|
||||||
:fnl/docstring "This function draws a filled circle of the desired radius and color with its center at x, y.
|
|
||||||
It uses the Bresenham algorithm.
|
|
||||||
"}}
|
|
||||||
:circb {:binding "circb"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "radius" "color"]
|
|
||||||
:fnl/docstring "Draws the circumference of a circle with its center at x, y using the radius and color requested.
|
|
||||||
It uses the Bresenham algorithm.
|
|
||||||
"}}
|
|
||||||
:clip {:binding "clip"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "width" "height"]
|
|
||||||
:fnl/docstring "This function limits drawing to a clipping region or `viewport` defined by x,y,w,h.
|
|
||||||
Things drawn outside of this area will not be visible.
|
|
||||||
Calling clip() with no parameters will reset the drawing area to the entire screen.
|
|
||||||
"}}
|
|
||||||
:cls {:binding "cls"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?color"]
|
|
||||||
:fnl/docstring "Clear the screen.
|
|
||||||
When called this function clear all the screen using the color passed as argument.
|
|
||||||
If no parameter is passed first color (0) is used.
|
|
||||||
"}}
|
|
||||||
:elli {:binding "elli"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "a" "b" "color"]
|
|
||||||
:fnl/docstring "This function draws a filled ellipse of the desired a, b radiuses and color with its center at x, y.
|
|
||||||
It uses the Bresenham algorithm.
|
|
||||||
"}}
|
|
||||||
:ellib {:binding "ellib"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "a" "b" "color"]
|
|
||||||
:fnl/docstring "This function draws an ellipse border with the desired radiuses a b and color with its center at x, y.
|
|
||||||
It uses the Bresenham algorithm.
|
|
||||||
"}}
|
|
||||||
:exit {:binding "exit"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "Interrupts program execution and returns to the console when the TIC function ends.
|
|
||||||
"}}
|
|
||||||
:fget {:binding "fget"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["sprite_id" "flag"]
|
|
||||||
:fnl/docstring "Returns true if the specified flag of the sprite is set. See `fset()` for more details.
|
|
||||||
"}}
|
|
||||||
:font {:binding "font"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["text"
|
|
||||||
"x"
|
|
||||||
"y"
|
|
||||||
"chromakey"
|
|
||||||
"char_width"
|
|
||||||
"char_height"
|
|
||||||
"?fixed"
|
|
||||||
"?scale"
|
|
||||||
"?alt"]
|
|
||||||
:fnl/docstring "Print string with font defined in foreground sprites.
|
|
||||||
To simply print to the screen, check out `print()`.
|
|
||||||
To print to the console, check out `trace()`.
|
|
||||||
"}}
|
|
||||||
:fset {:binding "fset"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["sprite_id" "flag" "bool"]
|
|
||||||
:fnl/docstring "Each sprite has eight flags which can be used to store information or signal different conditions.
|
|
||||||
For example, flag 0 might be used to indicate that the sprite is invisible, flag 6 might indicate that the flag should be draw scaled etc.
|
|
||||||
See algo `fget()`.
|
|
||||||
"}}
|
|
||||||
:key {:binding "key"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?code"]
|
|
||||||
:fnl/docstring "The function returns true if the key denoted by keycode is pressed.
|
|
||||||
"}}
|
|
||||||
:keyp {:binding "keyp"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?code" "?hold" "?period"]
|
|
||||||
:fnl/docstring "This function returns true if the given key is pressed but wasn't pressed in the previous frame.
|
|
||||||
Refer to `btnp()` for an explanation of the optional hold and period parameters.
|
|
||||||
"}}
|
|
||||||
:line {:binding "line"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x0" "y0" "x1" "y1" "color"]
|
|
||||||
:fnl/docstring "Draws a straight line from point (x0,y0) to point (x1,y1) in the specified color.
|
|
||||||
"}}
|
|
||||||
:map {:binding "map"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?x"
|
|
||||||
"?y"
|
|
||||||
"?w"
|
|
||||||
"?h"
|
|
||||||
"?sx"
|
|
||||||
"?sy"
|
|
||||||
"?colorkey"
|
|
||||||
"?scale"
|
|
||||||
"?remap"]
|
|
||||||
:fnl/docstring "The map consists of cells of 8x8 pixels, each of which can be filled with a sprite using the map editor.
|
|
||||||
The map can be up to 240 cells wide by 136 deep.
|
|
||||||
This function will draw the desired area of the map to a specified screen position.
|
|
||||||
For example, map(5,5,12,10,0,0) will draw a 12x10 section of the map, starting from map coordinates (5,5) to screen position (0,0).
|
|
||||||
The map function's last parameter is a powerful callback function for changing how map cells (sprites) are drawn when map is called.
|
|
||||||
It can be used to rotate, flip and replace sprites while the game is running.
|
|
||||||
Unlike mset, which saves changes to the map, this special function can be used to create animated tiles or replace them completely.
|
|
||||||
Some examples include changing sprites to open doorways, hiding sprites used to spawn objects in your game and even to emit the objects themselves.
|
|
||||||
The tilemap is laid out sequentially in RAM - writing 1 to 0x08000 will cause tile(sprite) #1 to appear at top left when map() is called.
|
|
||||||
To set the tile immediately below this we need to write to 0x08000 + 240, ie 0x080F0.
|
|
||||||
"}}
|
|
||||||
:memcpy {:binding "memcpy"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["dest" "source" "size"]
|
|
||||||
:fnl/docstring "This function allows you to copy a continuous block of TIC's 96K RAM from one address to another.
|
|
||||||
Addresses are specified are in hexadecimal format, values are decimal.
|
|
||||||
"}}
|
|
||||||
:memset {:binding "memset"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["dest" "value" "size"]
|
|
||||||
:fnl/docstring "This function allows you to set a continuous block of any part of TIC's RAM to the same value.
|
|
||||||
The address is specified in hexadecimal format, the value in decimal.
|
|
||||||
"}}
|
|
||||||
:mget {:binding "mget"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y"]
|
|
||||||
:fnl/docstring "Gets the sprite id at the given x and y map coordinate.
|
|
||||||
"}}
|
|
||||||
:mouse {:binding "mouse"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "This function returns the mouse coordinates and a boolean value for the state of each mouse button,with true indicating that a button is pressed.
|
|
||||||
"}}
|
|
||||||
:mset {:binding "mset"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "tile_id"]
|
|
||||||
:fnl/docstring "This function will change the tile at the specified map coordinates.
|
|
||||||
By default, changes made are only kept while the current game is running.
|
|
||||||
To make permanent changes to the map, see `sync()`.
|
|
||||||
Related: `map()` `mget()` `sync()`.
|
|
||||||
"}}
|
|
||||||
:music {:binding "music"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?track"
|
|
||||||
"?frame"
|
|
||||||
"?row"
|
|
||||||
"?loop"
|
|
||||||
"?sustain"
|
|
||||||
"?tempo"
|
|
||||||
"?speed"]
|
|
||||||
:fnl/docstring "This function starts playing a track created in the Music Editor.
|
|
||||||
Call without arguments to stop the music.
|
|
||||||
"}}
|
|
||||||
:peek {:binding "peek"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr" "?bits"]
|
|
||||||
:fnl/docstring "This function allows to read the memory from TIC.
|
|
||||||
It's useful to access resources created with the integrated tools like sprite, maps, sounds, cartridges data?
|
|
||||||
Never dream to sound a sprite?
|
|
||||||
Address are in hexadecimal format but values are decimal.
|
|
||||||
To write to a memory address, use `poke()`.
|
|
||||||
`bits` allowed to be 1,2,4,8.
|
|
||||||
"}}
|
|
||||||
:peek1 {:binding "peek1"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr"]
|
|
||||||
:fnl/docstring "This function enables you to read single bit values from TIC's RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
"}}
|
|
||||||
:peek2 {:binding "peek2"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr"]
|
|
||||||
:fnl/docstring "This function enables you to read two bits values from TIC's RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
"}}
|
|
||||||
:peek4 {:binding "peek4"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr"]
|
|
||||||
:fnl/docstring "This function enables you to read values from TIC's RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
See 'poke4()' for detailed information on how nibble addressing compares with byte addressing.
|
|
||||||
"}}
|
|
||||||
:pix {:binding "pix"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "color"]
|
|
||||||
:fnl/docstring "This function can read or write pixel color values.
|
|
||||||
When called with a color parameter, the pixel at the specified coordinates is set to that color.
|
|
||||||
Calling the function without a color parameter returns the color of the pixel at the specified position.
|
|
||||||
"}}
|
|
||||||
:pmem {:binding "pmem"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["index" "value"]
|
|
||||||
:fnl/docstring "This function allows you to save and retrieve data in one of the 256 individual 32-bit slots available in the cartridge's persistent memory.
|
|
||||||
This is useful for saving high-scores, level advancement or achievements.
|
|
||||||
The data is stored as unsigned 32-bit integers (from 0 to 4294967295).
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- pmem depends on the cartridge hash (md5), so don't change your lua script if you want to keep the data.
|
|
||||||
- Use `saveid:` with a personalized string in the header metadata to override the default MD5 calculation.
|
|
||||||
This allows the user to update a cart without losing their saved data.
|
|
||||||
"}}
|
|
||||||
:poke {:binding "poke"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr" "value" "?bits"]
|
|
||||||
:fnl/docstring "This function allows you to write a single byte to any address in TIC's RAM.
|
|
||||||
The address should be specified in hexadecimal format, the value in decimal.
|
|
||||||
`bits` allowed to be 1,2,4,8.
|
|
||||||
"}}
|
|
||||||
:poke1 {:binding "poke1"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr" "value"]
|
|
||||||
:fnl/docstring "This function allows you to write single bit values directly to RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
"}}
|
|
||||||
:poke2 {:binding "poke2"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr" "value"]
|
|
||||||
:fnl/docstring "This function allows you to write two bits values directly to RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
"}}
|
|
||||||
:poke4 {:binding "poke4"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["addr" "value"]
|
|
||||||
:fnl/docstring "This function allows you to write directly to RAM.
|
|
||||||
The address is often specified in hexadecimal format.
|
|
||||||
For both peek4 and poke4 RAM is addressed in 4 bit segments (nibbles).
|
|
||||||
Therefore, to access the the RAM at byte address 0x4000
|
|
||||||
you would need to access both the 0x8000 and 0x8001 nibble addresses.
|
|
||||||
"}}
|
|
||||||
:print {:binding "print"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["text"
|
|
||||||
"?x"
|
|
||||||
"?y"
|
|
||||||
"?color"
|
|
||||||
"?fixed"
|
|
||||||
"?scale"
|
|
||||||
"?smallfont"]
|
|
||||||
:fnl/docstring "This will simply print text to the screen using the font defined in config.
|
|
||||||
When set to true, the fixed width option ensures that each character will be printed in a `box` of the same size, so the character `i` will occupy the same width as the character `w` for example.
|
|
||||||
When fixed width is false, there will be a single space between each character.
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- To use a custom rastered font, check out `font()`.
|
|
||||||
- To print to the console, check out `trace()`.
|
|
||||||
"}}
|
|
||||||
:rect {:binding "rect"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "w" "h" "color"]
|
|
||||||
:fnl/docstring "This function draws a filled rectangle of the desired size and color at the specified position.
|
|
||||||
If you only need to draw the the border or outline of a rectangle (ie not filled) see `rectb()`.
|
|
||||||
"}}
|
|
||||||
:rectb {:binding "rectb"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x" "y" "w" "h" "color"]
|
|
||||||
:fnl/docstring "This function draws a one pixel thick rectangle border at the position requested.
|
|
||||||
If you need to fill the rectangle with a color, see `rect()` instead.
|
|
||||||
"}}
|
|
||||||
:reset {:binding "reset"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "Resets the cartridge. To return to the console, see the `exit()`.
|
|
||||||
"}}
|
|
||||||
:sfx {:binding "sfx"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["id"
|
|
||||||
"?note"
|
|
||||||
"?duration"
|
|
||||||
"?channel"
|
|
||||||
"?volume"
|
|
||||||
"?speed"]
|
|
||||||
:fnl/docstring "This function will play the sound with `id` created in the sfx editor.
|
|
||||||
Calling the function with id set to -1 will stop playing the channel.
|
|
||||||
The note can be supplied as an integer between 0 and 95 (representing 8 octaves of 12 notes each) or as a string giving the note name and octave.
|
|
||||||
For example, a note value of `14` will play the note `D` in the second octave.
|
|
||||||
The same note could be specified by the string `D-2`.
|
|
||||||
Note names consist of two characters, the note itself (in upper case) followed by `-` to represent the natural note or `#` to represent a sharp.
|
|
||||||
There is no option to indicate flat values.
|
|
||||||
The available note names are therefore: C-, C#, D-, D#, E-, F-, F#, G-, G#, A-, A#, B-.
|
|
||||||
The `octave` is specified using a single digit in the range 0 to 8.
|
|
||||||
The `duration` specifies how many ticks to play the sound for since TIC-80 runs at 60 frames per second, a value of 30 represents half a second.
|
|
||||||
A value of -1 will play the sound continuously.
|
|
||||||
The `channel` parameter indicates which of the four channels to use. Allowed values are 0 to 3.
|
|
||||||
The `volume` can be between 0 and 15.
|
|
||||||
The `speed` in the range -4 to 3 can be specified and means how many `ticks+1` to play each step, so speed==0 means 1 tick per step.
|
|
||||||
"}}
|
|
||||||
:spr {:binding "spr"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["id"
|
|
||||||
"x"
|
|
||||||
"y"
|
|
||||||
"?colorkey"
|
|
||||||
"?scale"
|
|
||||||
"?flip"
|
|
||||||
"?rotate"
|
|
||||||
"?w"
|
|
||||||
"?h"]
|
|
||||||
:fnl/docstring "Draws the sprite number index at the x and y coordinate.
|
|
||||||
You can specify a colorkey in the palette which will be used as the transparent color or use a value of -1 for an opaque sprite.
|
|
||||||
The sprite can be scaled up by a desired factor. For example, a scale factor of 2 means an 8x8 pixel sprite is drawn to a 16x16 area of the screen.
|
|
||||||
You can flip the sprite where:
|
|
||||||
- 0 = No Flip
|
|
||||||
- 1 = Flip horizontally
|
|
||||||
- 2 = Flip vertically
|
|
||||||
- 3 = Flip both vertically and horizontally
|
|
||||||
When you rotate the sprite, it's rotated clockwise in 90 steps:
|
|
||||||
- 0 = No rotation
|
|
||||||
- 1 = 90 rotation
|
|
||||||
- 2 = 180 rotation
|
|
||||||
- 3 = 270 rotation
|
|
||||||
You can draw a composite sprite (consisting of a rectangular region of sprites from the sprite sheet) by specifying the `w` and `h` parameters (which default to 1).
|
|
||||||
"}}
|
|
||||||
:sync {:binding "sync"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["?mask" "?bank" "?tocart"]
|
|
||||||
:fnl/docstring "The pro version of TIC-80 contains 8 memory banks.
|
|
||||||
To switch between these banks, sync can be used to either load contents from a memory bank to runtime, or save contents from the active runtime to a bank.
|
|
||||||
The function can only be called once per frame.If you have manipulated the runtime memory (e.g. by using mset), you can reset the active state by calling sync(0,0,false).
|
|
||||||
This resets the whole runtime memory to the contents of bank 0.Note that sync is not used to load code from banks; this is done automatically.
|
|
||||||
"}}
|
|
||||||
:time {:binding "time"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "This function returns the number of milliseconds elapsed since the cartridge began execution.
|
|
||||||
Useful for keeping track of time, animating items and triggering events.
|
|
||||||
"}}
|
|
||||||
:trace {:binding "trace"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["message" "?color"]
|
|
||||||
:fnl/docstring "This is a service function, useful for debugging your code.
|
|
||||||
It prints the message parameter to the console in the (optional) color specified.
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- The Lua concatenator for strings is .. (two points).
|
|
||||||
- Use console cls command to clear the output from trace.
|
|
||||||
"}}
|
|
||||||
:tri {:binding "tri"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x1" "y1" "x2" "y2" "x3" "y3" "color"]
|
|
||||||
:fnl/docstring "This function draws a triangle filled with color, using the supplied vertices.
|
|
||||||
"}}
|
|
||||||
:trib {:binding "trib"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x1" "y1" "x2" "y2" "x3" "y3" "color"]
|
|
||||||
:fnl/docstring "This function draws a triangle border with color, using the supplied vertices.
|
|
||||||
"}}
|
|
||||||
:tstamp {:binding "tstamp"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist {}
|
|
||||||
:fnl/docstring "This function returns the number of seconds elapsed since January 1st, 1970.
|
|
||||||
Useful for creating persistent games which evolve over time between plays.
|
|
||||||
"}}
|
|
||||||
:ttri {:binding "ttri"
|
|
||||||
:metadata {:fls/itemKind "Function"
|
|
||||||
:fnl/arglist ["x1"
|
|
||||||
"y1"
|
|
||||||
"x2"
|
|
||||||
"y2"
|
|
||||||
"x3"
|
|
||||||
"y3"
|
|
||||||
"u1"
|
|
||||||
"v1"
|
|
||||||
"u2"
|
|
||||||
"v2"
|
|
||||||
"u3"
|
|
||||||
"v3"
|
|
||||||
"?texsrc"
|
|
||||||
"?chromakey"
|
|
||||||
"?z1"
|
|
||||||
"?z2"
|
|
||||||
"?z3"]
|
|
||||||
:fnl/docstring "It renders a triangle filled with texture from image ram, map ram or vbank.
|
|
||||||
Use in 3D graphics.
|
|
||||||
In particular, if the vertices in the triangle have different 3D depth, you may see some distortion.
|
|
||||||
These can be thought of as the window inside image ram (sprite sheet), map ram or another vbank.
|
|
||||||
Note that the sprite sheet or map in this case is treated as a single large image, with U and V addressing its pixels directly, rather than by sprite ID.
|
|
||||||
So for example the top left corner of sprite #2 would be located at u=16, v=0.
|
|
||||||
"}}}
|
|
||||||
@ -179,9 +179,6 @@ except that it sets a new message handler `msgh`.")
|
|||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-libraries []
|
(fn test-libraries []
|
||||||
(check "#(trac|e :hello)"
|
|
||||||
#($:find "a service function")
|
|
||||||
{:libraries {:tic80 true}})
|
|
||||||
(check "(trans|late \"hello\" :en :zh)"
|
(check "(trans|late \"hello\" :en :zh)"
|
||||||
#($:find "convert from one lanugage to another")
|
#($:find "convert from one lanugage to another")
|
||||||
{:libraries {:external true}})
|
{:libraries {:external true}})
|
||||||
|
|||||||
@ -53,14 +53,6 @@
|
|||||||
(faith.not= [] bad))
|
(faith.not= [] bad))
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-native-libaries []
|
|
||||||
(let [{:diagnostics bad} (create-client {:main.fnl "(print btn)"
|
|
||||||
:flsproject.fnl "{}"})
|
|
||||||
{:diagnostics good} (create-client {:main.fnl "(print btn)"
|
|
||||||
:flsproject.fnl "{:libraries {:tic-80 true}}"})]
|
|
||||||
(faith.not= [] bad)
|
|
||||||
(faith.= [] good)))
|
|
||||||
|
|
||||||
(fn test-editing-settings []
|
(fn test-editing-settings []
|
||||||
(let [{: client : uri} (create-client {:main.fnl ""
|
(let [{: client : uri} (create-client {:main.fnl ""
|
||||||
:flsproject.fnl "{}"})
|
:flsproject.fnl "{}"})
|
||||||
@ -74,5 +66,4 @@
|
|||||||
{: test-path
|
{: test-path
|
||||||
: test-extra-globals
|
: test-extra-globals
|
||||||
: test-lints
|
: test-lints
|
||||||
: test-native-libaries
|
|
||||||
: test-editing-settings}
|
: test-editing-settings}
|
||||||
|
|||||||
227
tools/generate-lua-docs.fnl
Normal file
227
tools/generate-lua-docs.fnl
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
"Script to generate /src/fennel-ls/docs/lua54.fnl and friends automatically"
|
||||||
|
|
||||||
|
(local fennel (require :fennel))
|
||||||
|
(local util (require :tools.util))
|
||||||
|
|
||||||
|
(local index-pattern "<h2>.%.1 – <a name=\".%.1\">Basic Functions.-\n")
|
||||||
|
|
||||||
|
(fn parse-html [html]
|
||||||
|
"splits the lua manual into the relevant sections"
|
||||||
|
(let [begin-index (assert (html:find index-pattern) "no basic functions?")
|
||||||
|
end-index (assert (html:find "<h1>. – <a name=\".\".-\n" begin-index))
|
||||||
|
stdlib (html:sub begin-index (- end-index 1))
|
||||||
|
last-update (html:match "Last update:\n(.-)\n")
|
||||||
|
fields []
|
||||||
|
modules []]
|
||||||
|
(fn loop [prev]
|
||||||
|
(let [header (stdlib:find "<hr><h3>.-\n" (+ prev 1))
|
||||||
|
section (stdlib:sub prev (if header (- header 1)))]
|
||||||
|
(let [index (section:find "<h2>")]
|
||||||
|
(if index
|
||||||
|
(do
|
||||||
|
(table.insert fields (section:sub 1 (- index 1)))
|
||||||
|
(table.insert modules (section:sub index)))
|
||||||
|
(table.insert fields section)))
|
||||||
|
(when header (loop header))))
|
||||||
|
|
||||||
|
|
||||||
|
(fn make-title [name]
|
||||||
|
(.. "<hr><h3><a name=\"pdf-" name "\"><code>" name "</code></a></h3>\n"))
|
||||||
|
;; Artificially insert the `arg` docs.
|
||||||
|
;; This isn't present in the "Basic Functions" part of the manual, but is
|
||||||
|
;; still useful to be included in the docs.
|
||||||
|
(let [arg-signature (make-title :arg)
|
||||||
|
desc (-> html
|
||||||
|
;; The goal here is to extract the smallest string which:
|
||||||
|
;; 1) contains the string "global table called <code>arg</code>"
|
||||||
|
;; 2) ends with "\n<p>" (not inclusive)
|
||||||
|
;; 3) begins with "\n<p>" (not inclusive)
|
||||||
|
|
||||||
|
;; This match fufills 1 and 2
|
||||||
|
(: :match "(.*global table called <code>arg</code>.-)\n<p>")
|
||||||
|
;; trust me, I tried everything.
|
||||||
|
;; The best way to do 3 is a non-greedy search in reverse
|
||||||
|
(: :reverse)
|
||||||
|
(: :match "(.-)>p<\n")
|
||||||
|
(: :reverse))]
|
||||||
|
(table.insert fields (.. arg-signature desc)))
|
||||||
|
(table.insert fields (.. (make-title "io.stdin") "stdin file"))
|
||||||
|
(table.insert fields (.. (make-title "io.stdout") "stdout file"))
|
||||||
|
(table.insert fields (.. (make-title "io.stderr") "stderr file"))
|
||||||
|
(loop (stdlib:find "<hr><h3>.-\n"))
|
||||||
|
(values modules fields last-update)))
|
||||||
|
|
||||||
|
(fn html-to-markdown [str]
|
||||||
|
(let [str (-> str
|
||||||
|
;; delete <p> tags
|
||||||
|
(: :gsub "</?p>" "")
|
||||||
|
;; <code> tags for the rest
|
||||||
|
(: :gsub "\"<code>(.-)</code>\"" "`\"%1\"`")
|
||||||
|
(: :gsub "\'<code>(.-)</code>\'" "`\"%1\"`")
|
||||||
|
(: :gsub "<code>(.-)</code>" "`%1`")
|
||||||
|
;; supremum to unicode
|
||||||
|
(: :gsub "<sup>x</sup>" "ˣ")
|
||||||
|
(: :gsub "<sup>e</sup>" "ᵉ")
|
||||||
|
(: :gsub "<sup>y</sup>" "ʸ")
|
||||||
|
(: :gsub "<sup>51</sup>" "⁵¹")
|
||||||
|
(: :gsub "<sup>32</sup>" "³²")
|
||||||
|
; ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖ𐞥ʳˢᵗᵘᵛʷˣʸᶻ
|
||||||
|
;; bold to **
|
||||||
|
(: :gsub "<em>([^<]+)</em>" "*%1*")
|
||||||
|
(: :gsub "<b>([^<]+)</b>" "**%1**")
|
||||||
|
;; defeat all the links
|
||||||
|
(: :gsub "<a name=\"pdf%-[^\"]+\">([^<]+)</a>" "%1")
|
||||||
|
(: :gsub "<a href=\"#pdf%-[^\"]+\">([^<]+)</a>" "%1")
|
||||||
|
(: :gsub "<a href=\"#lua_[^\"]+\">([^<]+)</a>" "%1")
|
||||||
|
(: :gsub "See <a href=\"#[^\"]+\">[^<]+</a>[^%.]+%." "")
|
||||||
|
(: :gsub "[ \n]%(see <a href=\"#[^\"]+\">[^<]+</a>%)." "")
|
||||||
|
(: :gsub "[ \n]%(<a href=\"#[^\"]+\">[^<]+</a>%)." "")
|
||||||
|
;; code blocks
|
||||||
|
(: :gsub "<pre>\n?([^<]-)\n?</pre>" "```lua\n%1\n```")
|
||||||
|
;; list items to indented * thingies
|
||||||
|
(: :gsub "<li>([^<]+)</li>"
|
||||||
|
#(.. "* " (: ($:match "^\n*(.-)\n*$") :gsub "\n" "\n ")))
|
||||||
|
(: :gsub "</?ul>" ""))
|
||||||
|
;; check to ensure that all the tags have been defeated
|
||||||
|
tag (str:match "<[^>]+>[^>]+>")]
|
||||||
|
(when tag (error (.. "unhandled tag:" tag "\n" str)))
|
||||||
|
(-> str
|
||||||
|
;; trim whitespace
|
||||||
|
(: :match "^%s*(.-)%s*$")
|
||||||
|
;; html things
|
||||||
|
(: :gsub " " " ")
|
||||||
|
(: :gsub "–" "–")
|
||||||
|
(: :gsub "—" "—")
|
||||||
|
;; For some reason, they use an html middot, but we want to use periods.
|
||||||
|
(: :gsub "···" "...")
|
||||||
|
(: :gsub ">" ">")
|
||||||
|
(: :gsub "<" "<")
|
||||||
|
(: :gsub "&" "<")
|
||||||
|
(: :gsub "π" "π")
|
||||||
|
(: :gsub "\n\n+" "\n\n"))))
|
||||||
|
|
||||||
|
(fn parse-h3-section [html]
|
||||||
|
"parse a section that starts with an h3 tag. These are individual functions/variables."
|
||||||
|
(let [(header description) (html:match "^(.-)\n+(.-)\n*$")
|
||||||
|
optional-args []
|
||||||
|
signature (header:match "<code>(.-)</code>")
|
||||||
|
;; strip commas
|
||||||
|
signature (signature:gsub "," " ")
|
||||||
|
;; Replace `[]`'d args with ?-prefixes
|
||||||
|
;; Three times is enough, as `table.concat` and `load` and `loadfile`
|
||||||
|
;; and `utf8.codepoint` and `utf8.len` have 3 sets of []'s.
|
||||||
|
;; Lua 5.2 manual has a typo, so the last pass makes the `]` optional.
|
||||||
|
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%](%]-%))"
|
||||||
|
#(do (table.insert optional-args $1)
|
||||||
|
(.. :? $1 $2 $3)))
|
||||||
|
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%](%]-%))"
|
||||||
|
#(do (table.insert optional-args $1)
|
||||||
|
(.. :? $1 $2 $3)))
|
||||||
|
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%]?(%]-%))"
|
||||||
|
#(do (table.insert optional-args $1)
|
||||||
|
(.. :? $1 $2 $3)))
|
||||||
|
;; hide the thread argument in the debug functions
|
||||||
|
signature (if (signature:find "debug")
|
||||||
|
(signature:gsub "%[thread -%]" "")
|
||||||
|
signature)
|
||||||
|
;; hide the ?pos argument in table.insert
|
||||||
|
signature (if (signature:find "table%.insert")
|
||||||
|
(signature:gsub "%[pos -%]" "")
|
||||||
|
signature)
|
||||||
|
;; For some reason, they use an html middot, but we want to use periods.
|
||||||
|
signature (signature:gsub "···" "...")
|
||||||
|
;; fix parens
|
||||||
|
signature (signature:gsub "^(.-) -%(" "(%1 ")
|
||||||
|
;; fix spaces
|
||||||
|
signature (signature:gsub " +" " ")
|
||||||
|
signature (signature:gsub " +%)" ")")
|
||||||
|
signature-list (case (signature:match "^%((.-)%)$")
|
||||||
|
call (doto (icollect [arg (call:gmatch "[^ ]+")]
|
||||||
|
arg)
|
||||||
|
(table.remove 1)))
|
||||||
|
;; <code> tags for optional args
|
||||||
|
description (accumulate [desc description _ arg (ipairs optional-args)]
|
||||||
|
(desc:gsub (.. "<code>" arg "</code>") (.. "`?" arg "`")))
|
||||||
|
;; trim off the string pattern and string.pack/string.unpack format docs
|
||||||
|
description (description:gsub "\n[^\n]*<h3>.*" "")
|
||||||
|
description (html-to-markdown description)
|
||||||
|
name (signature:match "[^() ]+")
|
||||||
|
key (name:match "[^.:]+$")
|
||||||
|
?module (and (name:find "[.:]") (name:match "^[^.:]+"))
|
||||||
|
kind (if (signature:find "[()]") :Function :Variable)]
|
||||||
|
|
||||||
|
(values ?module
|
||||||
|
key
|
||||||
|
{:binding (signature:match "[^() ]+")
|
||||||
|
:metadata {:fnl/docstring description
|
||||||
|
:fnl/arglist signature-list
|
||||||
|
:fls/itemKind kind}})))
|
||||||
|
|
||||||
|
(fn parse-h2-section [html]
|
||||||
|
"parse a section that starts with an h2 tag. These are the main modules."
|
||||||
|
(let [(title description) (html:match "(.-)\n(.*)")
|
||||||
|
module-name (if (title:find "Coroutine")
|
||||||
|
"coroutine"
|
||||||
|
(title:find "Modules")
|
||||||
|
"package"
|
||||||
|
(title:find "String")
|
||||||
|
"string"
|
||||||
|
(title:find "UTF")
|
||||||
|
"utf8"
|
||||||
|
(title:find "Mathematical")
|
||||||
|
"math"
|
||||||
|
(title:find "Input and Output")
|
||||||
|
"io"
|
||||||
|
(title:find "Operating System")
|
||||||
|
"os"
|
||||||
|
(title:find "Debug")
|
||||||
|
"debug"
|
||||||
|
(title:find "Bitwise")
|
||||||
|
"bit32"
|
||||||
|
(title:find "Table")
|
||||||
|
"table")
|
||||||
|
description (html-to-markdown description)]
|
||||||
|
(assert module-name title)
|
||||||
|
(values module-name
|
||||||
|
{:binding module-name
|
||||||
|
:fields {}
|
||||||
|
:metadata {:fnl/docstring description
|
||||||
|
:fls/itemKind :Module}})))
|
||||||
|
|
||||||
|
(fn parse [input]
|
||||||
|
(let [version (input:match "Lua .- Reference Manual")
|
||||||
|
(modules module-items last-update) (parse-html input)
|
||||||
|
docs (collect [_ module (ipairs modules)]
|
||||||
|
(parse-h2-section module))]
|
||||||
|
(each [_ section (ipairs module-items)]
|
||||||
|
(let [(mod k v) (parse-h3-section section)]
|
||||||
|
(if (not mod)
|
||||||
|
(tset docs k v)
|
||||||
|
(not= mod "file")
|
||||||
|
(let [module-doc (. docs mod)]
|
||||||
|
(assert module-doc (.. mod " not found"))
|
||||||
|
(tset (. module-doc :fields) k v)))))
|
||||||
|
{: docs : last-update : version}))
|
||||||
|
|
||||||
|
(fn render [{: docs : last-update : version}]
|
||||||
|
(.. ";; Lua " version " last updated " last-update "\n"
|
||||||
|
(fennel.view (fennel.list (fennel.sym :local) (fennel.sym :docs) docs))
|
||||||
|
"\n(set docs._G.fields docs)\n"
|
||||||
|
"(set docs.io.fields.stdin.fields docs.io.fields)\n"
|
||||||
|
"(set docs.io.fields.stdout.fields docs.io.fields)\n"
|
||||||
|
"(set docs.io.fields.stderr.fields docs.io.fields)\n"
|
||||||
|
"docs"))
|
||||||
|
|
||||||
|
(fn derive-docs-for [version]
|
||||||
|
(let [v (assert (version:match "^lua5(.)$") "Invalid Lua version.")
|
||||||
|
url (string.format "https://www.lua.org/manual/5.%d/manual.html" v)
|
||||||
|
doc-tbl (render (parse (with-open [file (util.curl-cached url)]
|
||||||
|
(file:read :*a))))]
|
||||||
|
(print ";; auto-generated by `make docs` from fennel-ls. Contents come from")
|
||||||
|
(print ";;" url)
|
||||||
|
(print doc-tbl)))
|
||||||
|
|
||||||
|
(case arg
|
||||||
|
[version] (derive-docs-for version)
|
||||||
|
_ (do (io.stderr:write "USAGE: get-docs.fnl $VERSION\n")
|
||||||
|
(os.exit 1)))
|
||||||
@ -1,4 +1,4 @@
|
|||||||
(local {: sh} (require :tools.util.sh))
|
(local {: sh} (require :tools.util))
|
||||||
|
|
||||||
(fn git-clone [location url tag]
|
(fn git-clone [location url tag]
|
||||||
(if tag
|
(if tag
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
"Script to generate /src/fennel-ls/docs/lua54.fnl and friends automatically"
|
|
||||||
|
|
||||||
(local {: sh} (require :tools.util.sh))
|
|
||||||
|
|
||||||
(fn curl-cached [url]
|
|
||||||
(let [filename (.. "build/" (url:gsub "[/:]" "_"))
|
|
||||||
file (io.open filename :r)]
|
|
||||||
(if file
|
|
||||||
file
|
|
||||||
(do
|
|
||||||
(sh "curl" url [">"] filename)
|
|
||||||
(io.open filename :r)))))
|
|
||||||
|
|
||||||
(fn write-doc-file! [out-filename doc-src doc-tbl]
|
|
||||||
(assert doc-tbl
|
|
||||||
"bad argument #3, `doc-tbl` to write-doc-file! (expected string, got nil)")
|
|
||||||
(with-open [file (io.open (.. :src/fennel-ls/docs/generated/ out-filename) :w)]
|
|
||||||
(file:write ";; auto-generated by `make docs` from fennel-ls. Contents come from "
|
|
||||||
doc-src "\n" doc-tbl "\n")))
|
|
||||||
|
|
||||||
(fn derive-docs-from-url [url out-filename convert]
|
|
||||||
(write-doc-file! out-filename url
|
|
||||||
(convert (with-open [file (curl-cached url)]
|
|
||||||
(file:read :*a)))))
|
|
||||||
|
|
||||||
;; a lot of this should maybe be moved to the makefile?
|
|
||||||
(fn main []
|
|
||||||
(sh :mkdir :-p "build/")
|
|
||||||
(sh :mkdir :-p "src/fennel-ls/docs/generated/")
|
|
||||||
(let [generate-love2d-docs? (case arg ["--generate-love2d"] true _ false)
|
|
||||||
{:convert lua-manual} (require :tools.get-docs.lua-manual)
|
|
||||||
{:convert tic-manual} (require :tools.get-docs.tic80)]
|
|
||||||
(derive-docs-from-url "https://www.lua.org/manual/5.1/manual.html" "lua51.fnl" lua-manual)
|
|
||||||
(derive-docs-from-url "https://www.lua.org/manual/5.2/manual.html" "lua52.fnl" lua-manual)
|
|
||||||
(derive-docs-from-url "https://www.lua.org/manual/5.3/manual.html" "lua53.fnl" lua-manual)
|
|
||||||
(derive-docs-from-url "https://www.lua.org/manual/5.4/manual.html" "lua54.fnl" lua-manual)
|
|
||||||
(derive-docs-from-url "https://tic80.com/learn" :tic80.fnl tic-manual)
|
|
||||||
(when generate-love2d-docs?
|
|
||||||
(let [{:convert download-and-convert-love2d-manual!} (require :tools.get-docs.love2d)]
|
|
||||||
(write-doc-file! :love2d.fnl
|
|
||||||
"https://github.com/love2d-community/love-api/"
|
|
||||||
(download-and-convert-love2d-manual!))))))
|
|
||||||
|
|
||||||
(main)
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
(local fennel (require :fennel))
|
|
||||||
(local {:clone git-clone} (require :tools.util.git))
|
|
||||||
|
|
||||||
(local love-api-build-directory :build/love-api)
|
|
||||||
(local require-love-api
|
|
||||||
(partial require (.. love-api-build-directory :/love_api)))
|
|
||||||
|
|
||||||
;
|
|
||||||
; UTILS
|
|
||||||
; -----
|
|
||||||
(fn build-lsp-value [name ?args ?docstring ?fields ?kind]
|
|
||||||
"Takes ... and returns a table to be used with the LSP."
|
|
||||||
(let [lsp-value {:binding name}
|
|
||||||
?metadata (or ?args ?docstring)]
|
|
||||||
(when ?metadata (set lsp-value.metadata {}))
|
|
||||||
(when ?args (set lsp-value.metadata.fnl/arglist ?args))
|
|
||||||
(when ?docstring (set lsp-value.metadata.fnl/docstring ?docstring))
|
|
||||||
(when ?kind (set lsp-value.metadata.fls/itemKind ?kind))
|
|
||||||
(when ?fields (set lsp-value.fields ?fields))
|
|
||||||
lsp-value))
|
|
||||||
|
|
||||||
(fn clone-love-api! []
|
|
||||||
(when (not (io.open :build/love-api))
|
|
||||||
(git-clone love-api-build-directory
|
|
||||||
"https://github.com/love2d-community/love-api")))
|
|
||||||
|
|
||||||
(fn merge [...]
|
|
||||||
(let [arg-count (select "#" ...)
|
|
||||||
args [...]]
|
|
||||||
(if (= arg-count 0)
|
|
||||||
{}
|
|
||||||
(faccumulate [result {} i 1 arg-count]
|
|
||||||
(collect [k v (pairs (. args i)) &into result]
|
|
||||||
(values k v))))))
|
|
||||||
|
|
||||||
;
|
|
||||||
; PARSERS
|
|
||||||
; -------
|
|
||||||
(fn get-fn-argument-names [fn-arguments]
|
|
||||||
"Given an array of arguments, return all names as an array."
|
|
||||||
(icollect [_i {:description _ : name :type _} (ipairs fn-arguments)]
|
|
||||||
name))
|
|
||||||
|
|
||||||
(fn format-description-of-fn-return-values [fn-returns]
|
|
||||||
(accumulate [x "\n\nReturns -" _i {: description : name :type return-type} (ipairs fn-returns)]
|
|
||||||
(.. x "\n" " * " name " (`" return-type "`) - " description)))
|
|
||||||
|
|
||||||
(fn parse-first-fn-variant [[variant]]
|
|
||||||
"Given an array of fuction variants, format and return the first variant
|
|
||||||
for the LSP."
|
|
||||||
(collect [k v (pairs variant)]
|
|
||||||
(case k
|
|
||||||
:returns (values :returns (format-description-of-fn-return-values v))
|
|
||||||
:arguments (values :args (get-fn-argument-names v)))))
|
|
||||||
|
|
||||||
(fn get-all-love-api-functions [love-api]
|
|
||||||
[(table.unpack love-api.functions) (table.unpack love-api.callbacks)])
|
|
||||||
|
|
||||||
(fn love-functions->lsp-table [docs-tbl namespace]
|
|
||||||
(collect [_i value (ipairs docs-tbl)]
|
|
||||||
(let [{: name : description} value
|
|
||||||
binding (.. namespace name)
|
|
||||||
?variants (?. value :variants)
|
|
||||||
; LÖVE functions have several variants, e.g. different arities or
|
|
||||||
; types; however, it's uncertain how to best display all of that
|
|
||||||
; information, so the first is selected here as a reasonable default.
|
|
||||||
first-variant (if ?variants
|
|
||||||
(parse-first-fn-variant ?variants)
|
|
||||||
nil)
|
|
||||||
?args (?. first-variant :args)
|
|
||||||
?returns (or (?. first-variant :returns) "")
|
|
||||||
docstring (.. description ?returns)]
|
|
||||||
(values name (build-lsp-value binding ?args docstring nil :Function)))))
|
|
||||||
|
|
||||||
(fn module-list->lsp-table [modules ?namespace]
|
|
||||||
(collect [_i module (ipairs modules)]
|
|
||||||
(let [{: name} module ; Other keys - :enum, :functions, :types
|
|
||||||
namespace (if ?namespace (.. ?namespace ".") "")
|
|
||||||
binding (.. namespace name)
|
|
||||||
?docstring (?. module :description)
|
|
||||||
?functions (?. module :functions)
|
|
||||||
?modules (?. module :modules)
|
|
||||||
function-keys (if ?functions
|
|
||||||
(love-functions->lsp-table ?functions (.. binding "."))
|
|
||||||
{})
|
|
||||||
module-keys (if ?modules (module-list->lsp-table ?modules binding) {})
|
|
||||||
fields (merge function-keys module-keys)]
|
|
||||||
(values name (build-lsp-value binding nil ?docstring fields :Module)))))
|
|
||||||
|
|
||||||
(fn love-api->lsp-table [love-api]
|
|
||||||
(let [root-module {:description (.. "LÖVE is a framework for making 2D "
|
|
||||||
"games in the Lua programming language.")
|
|
||||||
:functions (get-all-love-api-functions love-api)
|
|
||||||
:modules love-api.modules
|
|
||||||
:name :love}]
|
|
||||||
(module-list->lsp-table [root-module])))
|
|
||||||
|
|
||||||
(fn convert []
|
|
||||||
"Download documentation for the LÖVE framework via the love-api repo and
|
|
||||||
convert it to a Lua table usable for fennel-ls."
|
|
||||||
(clone-love-api!)
|
|
||||||
(let [love-api (require-love-api)]
|
|
||||||
(fennel.view (love-api->lsp-table love-api))))
|
|
||||||
|
|
||||||
{: convert}
|
|
||||||
@ -1,206 +0,0 @@
|
|||||||
(fn parse-html [html]
|
|
||||||
"splits the lua manual into the relevant sections"
|
|
||||||
(let [begin-index (assert (html:find "<h2>.%.1 – <a name=\".%.1\">Basic Functions.-\n") "no basic functions?")
|
|
||||||
end-index (assert (html:find "<h1>. – <a name=\".\".-\n" begin-index))
|
|
||||||
stdlib (html:sub begin-index (- end-index 1))
|
|
||||||
last-update (html:match "Last update:\n(.-)\n")
|
|
||||||
fields []
|
|
||||||
modules []]
|
|
||||||
(fn loop [prev]
|
|
||||||
(let [header (stdlib:find "<hr><h3>.-\n" (+ prev 1))
|
|
||||||
section (stdlib:sub prev (if header (- header 1)))]
|
|
||||||
(let [index (section:find "<h2>")]
|
|
||||||
(if index
|
|
||||||
(do
|
|
||||||
(table.insert fields (section:sub 1 (- index 1)))
|
|
||||||
(table.insert modules (section:sub index)))
|
|
||||||
(table.insert fields section)))
|
|
||||||
(when header (loop header))))
|
|
||||||
|
|
||||||
|
|
||||||
(fn make-title [name]
|
|
||||||
(.. "<hr><h3><a name=\"pdf-" name "\"><code>" name "</code></a></h3>\n"))
|
|
||||||
;; Artificially insert the `arg` docs.
|
|
||||||
;; This isn't present in the "Basic Functions" part of the manual, but is still useful to be included in the docs.
|
|
||||||
(let [arg-signature (make-title :arg)
|
|
||||||
arg-description (-> html
|
|
||||||
;; The goal here is to extract the smallest string which:
|
|
||||||
;; 1) contains the string "global table called <code>arg</code>"
|
|
||||||
;; 2) ends with "\n<p>" (not inclusive)
|
|
||||||
;; 3) begins with "\n<p>" (not inclusive)
|
|
||||||
|
|
||||||
;; This match fufills 1 and 2
|
|
||||||
(: :match "(.*global table called <code>arg</code>.-)\n<p>")
|
|
||||||
;; trust me, I tried everything.
|
|
||||||
;; The best way to do 3 is a non-greedy search in reverse
|
|
||||||
(: :reverse)
|
|
||||||
(: :match "(.-)>p<\n")
|
|
||||||
(: :reverse))]
|
|
||||||
(table.insert fields (.. arg-signature arg-description)))
|
|
||||||
(table.insert fields (.. (make-title "io.stdin") "stdin file"))
|
|
||||||
(table.insert fields (.. (make-title "io.stdout") "stdout file"))
|
|
||||||
(table.insert fields (.. (make-title "io.stderr") "stderr file"))
|
|
||||||
(loop (stdlib:find "<hr><h3>.-\n"))
|
|
||||||
(values modules fields last-update)))
|
|
||||||
|
|
||||||
(fn html-to-markdown [str]
|
|
||||||
(let [str
|
|
||||||
(-> str
|
|
||||||
;; delete <p> tags
|
|
||||||
(: :gsub "</?p>" "")
|
|
||||||
;; <code> tags for the rest
|
|
||||||
(: :gsub "\"<code>(.-)</code>\"" "`\"%1\"`")
|
|
||||||
(: :gsub "\'<code>(.-)</code>\'" "`\"%1\"`")
|
|
||||||
(: :gsub "<code>(.-)</code>" "`%1`")
|
|
||||||
;; supremum to unicode
|
|
||||||
(: :gsub "<sup>x</sup>" "ˣ")
|
|
||||||
(: :gsub "<sup>e</sup>" "ᵉ")
|
|
||||||
(: :gsub "<sup>y</sup>" "ʸ")
|
|
||||||
(: :gsub "<sup>51</sup>" "⁵¹")
|
|
||||||
(: :gsub "<sup>32</sup>" "³²")
|
|
||||||
; ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖ𐞥ʳˢᵗᵘᵛʷˣʸᶻ
|
|
||||||
;; bold to **
|
|
||||||
(: :gsub "<em>([^<]+)</em>" "*%1*")
|
|
||||||
(: :gsub "<b>([^<]+)</b>" "**%1**")
|
|
||||||
;; defeat all the links
|
|
||||||
(: :gsub "<a name=\"pdf%-[^\"]+\">([^<]+)</a>" "%1")
|
|
||||||
(: :gsub "<a href=\"#pdf%-[^\"]+\">([^<]+)</a>" "%1")
|
|
||||||
(: :gsub "<a href=\"#lua_[^\"]+\">([^<]+)</a>" "%1")
|
|
||||||
(: :gsub "See <a href=\"#[^\"]+\">[^<]+</a>[^%.]+%." "")
|
|
||||||
(: :gsub "[ \n]%(see <a href=\"#[^\"]+\">[^<]+</a>%)." "")
|
|
||||||
(: :gsub "[ \n]%(<a href=\"#[^\"]+\">[^<]+</a>%)." "")
|
|
||||||
;; code blocks
|
|
||||||
(: :gsub "<pre>\n?([^<]-)\n?</pre>" "```lua\n%1\n```")
|
|
||||||
;; list items to indented * thingies
|
|
||||||
(: :gsub "<li>([^<]+)</li>" #(.. "* " (: ($:match "^\n*(.-)\n*$") :gsub "\n" "\n ")))
|
|
||||||
(: :gsub "</?ul>" ""))
|
|
||||||
;; check to ensure that all the tags have been defeated
|
|
||||||
tag (str:match "<[^>]+>[^>]+>")]
|
|
||||||
(when tag (error (.. "unhandled tag:" tag "\n" str)))
|
|
||||||
(-> str
|
|
||||||
;; trim whitespace
|
|
||||||
(: :match "^%s*(.-)%s*$")
|
|
||||||
;; html things
|
|
||||||
(: :gsub " " " ")
|
|
||||||
(: :gsub "–" "–")
|
|
||||||
(: :gsub "—" "—")
|
|
||||||
;; For some reason, they use an html middot, but we want to use periods.
|
|
||||||
(: :gsub "···" "...")
|
|
||||||
(: :gsub ">" ">")
|
|
||||||
(: :gsub "<" "<")
|
|
||||||
(: :gsub "&" "<")
|
|
||||||
(: :gsub "π" "π")
|
|
||||||
(: :gsub "\n\n+" "\n\n"))))
|
|
||||||
|
|
||||||
(fn parse-h3-section [html]
|
|
||||||
"parse a section that starts with an h3 tag. These are individual functions/variables."
|
|
||||||
(let [(header description) (html:match "^(.-)\n+(.-)\n*$")
|
|
||||||
optional-args []
|
|
||||||
signature (header:match "<code>(.-)</code>")
|
|
||||||
;; strip commas
|
|
||||||
signature (signature:gsub "," " ")
|
|
||||||
;; Replace `[]`'d args with ?-prefixes
|
|
||||||
;; Three times is enough, as `table.concat` and `load` and `loadfile`
|
|
||||||
;; and `utf8.codepoint` and `utf8.len` have 3 sets of []'s.
|
|
||||||
;; Lua 5.2 manual has a typo, so the last pass makes the `]` optional.
|
|
||||||
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%](%]-%))"
|
|
||||||
#(do (table.insert optional-args $1) (.. :? $1 $2 $3)))
|
|
||||||
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%](%]-%))"
|
|
||||||
#(do (table.insert optional-args $1) (.. :? $1 $2 $3)))
|
|
||||||
signature (signature:gsub "%[ -([^%[%] ]+)([^%[%]]-)%]?(%]-%))"
|
|
||||||
#(do (table.insert optional-args $1) (.. :? $1 $2 $3)))
|
|
||||||
;; hide the thread argument in the debug functions
|
|
||||||
signature (if (signature:find "debug") (signature:gsub "%[thread -%]" "") signature)
|
|
||||||
;; hide the ?pos argument in table.insert
|
|
||||||
signature (if (signature:find "table%.insert") (signature:gsub "%[pos -%]" "") signature)
|
|
||||||
;; For some reason, they use an html middot, but we want to use periods.
|
|
||||||
signature (signature:gsub "···" "...")
|
|
||||||
;; fix parens
|
|
||||||
signature (signature:gsub "^(.-) -%(" "(%1 ")
|
|
||||||
;; fix spaces
|
|
||||||
signature (signature:gsub " +" " ")
|
|
||||||
signature (signature:gsub " +%)" ")")
|
|
||||||
signature-list (case (signature:match "^%((.-)%)$")
|
|
||||||
call (doto (icollect [arg (call:gmatch "[^ ]+")]
|
|
||||||
arg)
|
|
||||||
(table.remove 1)))
|
|
||||||
;; <code> tags for optional args
|
|
||||||
description (accumulate [description description _ arg (ipairs optional-args)]
|
|
||||||
(description:gsub (.. "<code>" arg "</code>")
|
|
||||||
(.. "`?" arg "`")))
|
|
||||||
;; trim off the string pattern and string.pack/string.unpack format docs
|
|
||||||
description (description:gsub "\n[^\n]*<h3>.*" "")
|
|
||||||
description (html-to-markdown description)
|
|
||||||
name (signature:match "[^() ]+")
|
|
||||||
key (name:match "[^.:]+$")
|
|
||||||
?module (and (name:find "[.:]") (name:match "^[^.:]+"))
|
|
||||||
kind (if (signature:find "[()]") :Function :Variable)]
|
|
||||||
|
|
||||||
(values ?module
|
|
||||||
key
|
|
||||||
{:binding (signature:match "[^() ]+")
|
|
||||||
:metadata {:fnl/docstring description
|
|
||||||
:fnl/arglist signature-list
|
|
||||||
:fls/itemKind kind}})))
|
|
||||||
|
|
||||||
(fn parse-h2-section [html]
|
|
||||||
"parse a section that starts with an h2 tag. These are the main modules."
|
|
||||||
(let [(title description) (html:match "(.-)\n(.*)")
|
|
||||||
module-name (if (title:find "Coroutine")
|
|
||||||
"coroutine"
|
|
||||||
(title:find "Modules")
|
|
||||||
"package"
|
|
||||||
(title:find "String")
|
|
||||||
"string"
|
|
||||||
(title:find "UTF")
|
|
||||||
"utf8"
|
|
||||||
(title:find "Mathematical")
|
|
||||||
"math"
|
|
||||||
(title:find "Input and Output")
|
|
||||||
"io"
|
|
||||||
(title:find "Operating System")
|
|
||||||
"os"
|
|
||||||
(title:find "Debug")
|
|
||||||
"debug"
|
|
||||||
(title:find "Bitwise")
|
|
||||||
"bit32"
|
|
||||||
(title:find "Table")
|
|
||||||
"table")
|
|
||||||
description (html-to-markdown description)]
|
|
||||||
(assert module-name title)
|
|
||||||
(values module-name
|
|
||||||
{:binding module-name
|
|
||||||
:fields {}
|
|
||||||
:metadata {:fnl/docstring description
|
|
||||||
:fls/itemKind :Module}})))
|
|
||||||
|
|
||||||
(fn parse [input]
|
|
||||||
(let [version (input:match "Lua .- Reference Manual")
|
|
||||||
(modules module-items last-update) (parse-html input)
|
|
||||||
docs (collect [_ module (ipairs modules)]
|
|
||||||
(parse-h2-section module))]
|
|
||||||
(each [_ section (ipairs module-items)]
|
|
||||||
(let [(mod k v) (parse-h3-section section)]
|
|
||||||
(if (not mod)
|
|
||||||
(tset docs k v)
|
|
||||||
(not= mod "file")
|
|
||||||
(let [module-doc (. docs mod)]
|
|
||||||
(assert module-doc (.. mod " not found"))
|
|
||||||
(tset (. module-doc :fields) k v)))))
|
|
||||||
{: docs : last-update : version}))
|
|
||||||
|
|
||||||
(fn render [{: docs : last-update : version}]
|
|
||||||
(let [{: view : sym : list} (require :fennel)]
|
|
||||||
(..
|
|
||||||
";; Lua " version " last updated " last-update "\n"
|
|
||||||
(view (list (sym :local) (sym :docs) docs)) "\n"
|
|
||||||
"(set docs._G.fields docs)\n"
|
|
||||||
"(set docs.io.fields.stdin.fields docs.io.fields)\n"
|
|
||||||
"(set docs.io.fields.stdout.fields docs.io.fields)\n"
|
|
||||||
"(set docs.io.fields.stderr.fields docs.io.fields)\n"
|
|
||||||
"docs")))
|
|
||||||
|
|
||||||
(fn convert [input]
|
|
||||||
(render (parse input)))
|
|
||||||
|
|
||||||
{: convert}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
(local fennel (require :fennel))
|
|
||||||
|
|
||||||
(fn remove-html-escape-codes [x]
|
|
||||||
(-> x
|
|
||||||
(: :gsub " " " ")
|
|
||||||
(: :gsub "–" "–")
|
|
||||||
(: :gsub "—" "—")
|
|
||||||
(: :gsub ">" ">")
|
|
||||||
(: :gsub "<" "<")
|
|
||||||
(: :gsub "&" "<")
|
|
||||||
(: :gsub "π" "π")))
|
|
||||||
|
|
||||||
(fn markdown->arglist [markdown]
|
|
||||||
(case (markdown:match "%(([^%)]*)%)")
|
|
||||||
signature
|
|
||||||
(icollect [arg (signature:gmatch "%S+")]
|
|
||||||
(case (arg:match "(.*)=")
|
|
||||||
argname (.. "?" argname)
|
|
||||||
_ arg))))
|
|
||||||
|
|
||||||
(fn markdown->data [html]
|
|
||||||
(let [api-markdown (html:match "## API functions.-### (.*)## Button IDs")
|
|
||||||
api-markdown (remove-html-escape-codes api-markdown)]
|
|
||||||
(collect [(name args docs) (api-markdown:gmatch
|
|
||||||
"([_%w]+)%s+`([^`]+)`%s(.-)\n### ")]
|
|
||||||
(let [arglist (markdown->arglist args)]
|
|
||||||
(values name {:metadata {:fnl/arglist arglist
|
|
||||||
:fnl/docstring docs
|
|
||||||
:fls/itemKind :Function}
|
|
||||||
:binding name})))))
|
|
||||||
|
|
||||||
(fn convert [contents]
|
|
||||||
(fennel.view (markdown->data contents)))
|
|
||||||
|
|
||||||
{: convert}
|
|
||||||
@ -17,4 +17,19 @@
|
|||||||
(print (.. "running command: " command))
|
(print (.. "running command: " command))
|
||||||
(assert (os.execute command))))
|
(assert (os.execute command))))
|
||||||
|
|
||||||
{: sh}
|
(fn clone [location url ?tag]
|
||||||
|
"Clones a git repository, given a location, url, and optional tag."
|
||||||
|
(assert location "Expected file location to clone git repository into.")
|
||||||
|
(assert url "Expected git repository url to clone.")
|
||||||
|
(if ?tag
|
||||||
|
(sh :git :clone :-c :advice.detachedHead=false :--depth=1 :--branch ?tag
|
||||||
|
url location)
|
||||||
|
(sh :git :clone :-c :advice.detachedHead=false :--depth=1 url location)))
|
||||||
|
|
||||||
|
(fn curl-cached [url]
|
||||||
|
(let [filename (.. "build/" (url:gsub "[/:]" "_"))]
|
||||||
|
(or (io.open filename)
|
||||||
|
(do (sh "curl" url [">"] filename)
|
||||||
|
(io.open filename)))))
|
||||||
|
|
||||||
|
{: sh : clone : curl-cached}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
(local {: sh} (require :tools.util.sh))
|
|
||||||
|
|
||||||
(fn clone [location url ?tag]
|
|
||||||
"Clones a git repository, given a location, url, and optional tag."
|
|
||||||
(assert location "Expected file location to clone git repository into.")
|
|
||||||
(assert url "Expected git repository url to clone.")
|
|
||||||
(if ?tag
|
|
||||||
(sh :git :clone :-c :advice.detachedHead=false :--depth=1 :--branch ?tag
|
|
||||||
url location)
|
|
||||||
(sh :git :clone :-c :advice.detachedHead=false :--depth=1 url location)))
|
|
||||||
|
|
||||||
{: clone}
|
|
||||||
Loading…
Reference in New Issue
Block a user