Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
Omikhleia authored and Didier Willis committed Aug 4, 2023
1 parent 6227538 commit 42462c3
Show file tree
Hide file tree
Showing 10 changed files with 567 additions and 1 deletion.
13 changes: 13 additions & 0 deletions .github/workflows/luacheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Luacheck

on: [push, pull_request]

jobs:

luacheck:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Luacheck
uses: lunarmodules/luacheck@v0
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Compiled Lua sources
luac.out

# luarocks build files
*.src.rock
*.zip
*.tar.gz

# Object files
*.o
*.os
*.ko
*.obj
*.elf

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp

# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

# SILE artifacts
*.toc
*.ref
tests/*.pdf
tests/*.debug

35 changes: 35 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
std = "max"
include_files = {
"**/*.lua",
"sile.in",
"*.rockspec",
".busted",
".luacheckrc"
}
exclude_files = {
"benchmark-*",
"compare-*",
"sile-*",
"lua_modules",
"lua-libraries",
".lua",
".luarocks",
".install"
}
files["**/*_spec.lua"] = {
std = "+busted"
}
globals = {
"SILE",
"SU",
"luautf8",
"pl",
"fluent",
"SYSTEM_SILE_PATH",
"SHARED_LIB_EXT"
}
max_line_length = false
ignore = {
"581" -- operator order warning doesn't account for custom table metamethods
}
-- vim: ft=lua
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
# silex.sile
Extension layer for SILE and resilient

[![license](https://img.shields.io/github/license/Omikhleia/silex.sile?label=License)](LICENSE)
[![Luacheck](https://img.shields.io/github/actions/workflow/status/Omikhleia/silex.sile/luacheck.yml?branch=main&label=Luacheck&logo=Lua)](https://github.com/Omikhleia/silex.sile/actions?workflow=Luacheck)
[![Luarocks](https://img.shields.io/luarocks/v/Omikhleia/silex.sile?label=Luarocks&logo=Lua)](https://luarocks.org/modules/Omikhleia/silex.sile)

This is **sile·x**, a common layer for [**re·sil·ient**](https://github.com/Omikhleia/resilient.sile) and other modules:
Some common bricks, compatility features, opinionated hacks, and eXperimental eXpansions, hence the name.

## License

All code is under the MIT License.
27 changes: 27 additions & 0 deletions silex.sile-dev-1.rockspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package = "silex.sile"
version = "dev-1"
source = {
url = "git+https://github.com/Omikhleia/silex.sile.git",
}
description = {
summary = "Extension layer for SILE and resilient",
detailed = [[
Some common bricks, compatility features, opinionated hacks,
and eXperimental eXpansions.
]],
homepage = "https://github.com/Omikhleia/silex.sile",
license = "MIT",
}
dependencies = {
"lua >= 5.1",
}
build = {
type = "builtin",
modules = {
["sile.silex"] = "silex/init.lua",
["sile.silex.fork"] = "silex/fork.lua",
["sile.silex.lang"] = "silex/lang.lua",
["sile.silex.fixes"] = "silex/fixes.lua",
["sile.silex.compat"] = "silex/compat.lua",
}
}
200 changes: 200 additions & 0 deletions silex/compat.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
SILE.X = SILE.X or {}

-- Loosely inspired from https://github.com/kikito/semver.lua
-- (MIT License (c) 2011 Enrique García Cota)
-- but simplified to our bare needs.
local semver = {}
local mt = {}
function mt:__eq(other)
return self.major == other.major and
self.minor == other.minor and
self.patch == other.patch
end
function mt:__lt(other)
if self.major ~= other.major then return self.major < other.major end
if self.minor ~= other.minor then return self.minor < other.minor end
if self.patch ~= other.patch then return self.patch < other.patch end
return false
end
function mt:__le(other)
if self.major ~= other.major then return self.major <= other.major end
if self.minor ~= other.minor then return self.minor <= other.minor end
if self.patch ~= other.patch then return self.patch <= other.patch end
return true
end
function mt:__tostring()
return ("%d.%d.%d"):format(self.major, self.minor, self.patch)
end
local function new(vstr)
local major, minor, patch = vstr:match("^v?(%d+)%.(%d+)%.(%d+)")
local result = { major = tonumber(major), minor = tonumber(minor), patch = tonumber(patch) }
if not result.major and not result.minor and not result.patch then
SU.error("Invalid version string: "..vstr)
end
local o = setmetatable(result, mt)
return o
end
setmetatable(semver, { __call = function(_, ...) return new(...) end })

local SILEVERSION = semver(SILE.version)

-- Compat: parindent issue
if SILEVERSION >= semver("0.14.9") then
SU.debug("silex", "No need for patching SILE (parindent issue)")
else
SU.debug("silex", "Patching SILE (parindent issue)")

local class = require("classes.plain")
function class.newPar (typesetter)
local parindent = SILE.settings:get("current.parindent") or SILE.settings:get("document.parindent")
typesetter:pushGlue(parindent:absolute()) -- HACK
SILE.settings:set("current.parindent", nil)
local hangIndent = SILE.settings:get("current.hangIndent")
if hangIndent then
SILE.settings:set("linebreak.hangIndent", hangIndent)
end
local hangAfter = SILE.settings:get("current.hangAfter")
if hangAfter then
SILE.settings:set("linebreak.hangAfter", hangAfter)
end
end
end

-- Compat: hbox building logic
local typesetter = require("typesetters.base")
if typesetter.makeHbox then
SU.debug("silex", "No need for patching typesetter (hbox support)")
else
SU.debug("silex", "Patching typesetter (hbox support from SILE 0.14.9)")
if SILEVERSION >= semver("0.14.9") then
SU.warn("SILE version "..SILE.version.." should not have needed patching hbox support")
end

local _rtl_pre_post = function (box, atypesetter, line)
local advance = function () atypesetter.frame:advanceWritingDirection(box:scaledWidth(line)) end
if atypesetter.frame:writingDirection() == "RTL" then
advance()
return function () end
else
return advance
end
end

function typesetter:makeHbox (content)
local recentContribution = {}
local migratingNodes = {}

local index = #(self.state.nodes)+1
self.state.hmodeOnly = true
SILE.process(content)
self.state.hmodeOnly = false

local l = SILE.length()
local h, d = SILE.length(), SILE.length()
for i = index, #(self.state.nodes) do
local node = self.state.nodes[i]
if node.is_migrating then
migratingNodes[#migratingNodes+1] = node
elseif node.is_unshaped then
local shape = node:shape()
for _, attr in ipairs(shape) do
recentContribution[#recentContribution+1] = attr
h = attr.height > h and attr.height or h
d = attr.depth > d and attr.depth or d
l = l + attr:lineContribution():absolute()
end
elseif node.is_discretionary then
recentContribution[#recentContribution+1] = node
l = l + node:replacementWidth():absolute()
local hdisc = node:replacementHeight():absolute()
local ddisc = node:replacementDepth():absolute()
h = hdisc > h and hdisc or h
d = ddisc > d and ddisc or d
else
recentContribution[#recentContribution+1] = node
l = l + node:lineContribution():absolute()
h = node.height > h and node.height or h
d = node.depth > d and node.depth or d
end
self.state.nodes[i] = nil
end

local hbox = SILE.nodefactory.hbox({
height = h,
width = l,
depth = d,
value = recentContribution,
outputYourself = function (box, atypesetter, line)
local _post = _rtl_pre_post(box, atypesetter, line)
local ox = atypesetter.frame.state.cursorX
local oy = atypesetter.frame.state.cursorY
SILE.outputter:setCursor(atypesetter.frame.state.cursorX, atypesetter.frame.state.cursorY)
for _, node in ipairs(box.value) do
node:outputYourself(atypesetter, line)
end
atypesetter.frame.state.cursorX = ox
atypesetter.frame.state.cursorY = oy
_post()
SU.debug("hboxes", function ()
SILE.outputter:debugHbox(box, box:scaledWidth(line))
return "Drew debug outline around hbox"
end)
end
})
return hbox, migratingNodes
end

function typesetter:pushHlist (hlist)
for _, h in ipairs(hlist) do
self:pushHorizontal(h)
end
end
end

-- Compat: content pos stripping utility
if SU.stripContentPos then
SU.debug("silex", "No need for patching utilities (AST position stripping)")
else
SU.debug("silex", "Patching utilities (AST position stripping from SILE 0.14.9)")
if SILEVERSION >= semver("0.14.9") then
SU.warn("SILE version "..SILE.version.." should not have needed patching AST position stripping")
end

SU.stripContentPos = function (content)
if type(content) ~= "table" then
return content
end
local stripped = {}
for k, v in pairs(content) do
if type(v) == "table" then
v = SU.stripContentPos(v)
end
stripped[k] = v
end
if content.id or content.command then
stripped.pos, stripped.col, stripped.lno = nil, nil, nil
end
return stripped
end
end

-- Compat: issues fixed in 0.14.9
-- No easy way to do feature detection, so we just check the version.
if SILEVERSION < semver("0.14.9") then
SU.debug("silex", "Patching pre-0.14.9 issues")
SILE.settings.declare = function (self, spec)
if self.declarations[spec.parameter] then -- HACK
return SU.debug("silex", "Settings redeclaration ignored ", spec.parameter)
end
self.declarations[spec.parameter] = spec
self:set(spec.parameter, spec.default, true)
end
-- See https://github.com/sile-typesetter/sile/issues/1718
local oldInitLine = SILE.typesetters.base.initline
SILE.typesetters.base.initline = function (self)
if self.state.hmodeOnly then return end
oldInitLine(self)
end
else
SU.debug("silex", "No need for patching pre-0.14.9 issues")
end
7 changes: 7 additions & 0 deletions silex/fixes.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Annoyingly, inputters options can be nil
local inputter = require("inputters.base")
local oldInit = inputter._init
function inputter:_init (options)
oldInit(self, options)
self.options = self.options or {}
end
Loading

0 comments on commit 42462c3

Please sign in to comment.