diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b5bcc1c59..e3f9e3af7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,7 +81,7 @@ jobs: .sources key: fonts-${{ hashFiles('Makefile-fonts') }} - name: Install Nix - uses: DeterminateSystems/nix-installer-action@v5 + uses: DeterminateSystems/nix-installer-action@v6 - name: Cache Nix dependencies uses: DeterminateSystems/magic-nix-cache-action@v2 - name: Setup developer environment diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index bd067ce30..20befbf78 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -16,7 +16,7 @@ jobs: with: fetch-depth: 0 - name: Install Nix - uses: DeterminateSystems/nix-installer-action@v5 + uses: DeterminateSystems/nix-installer-action@v6 - name: Cache Nix dependencies uses: DeterminateSystems/magic-nix-cache-action@v2 # Upstream package sometimes has flags set that disable flake checking diff --git a/CHANGELOG.md b/CHANGELOG.md index e55f47620..2cde910bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.14.13](https://github.com/sile-typesetter/sile/compare/v0.14.12...v0.14.13) (2023-10-30) + + +### Features + +* **classes:** Add landscape option to base class ([#1892](https://github.com/sile-typesetter/sile/issues/1892)) ([0fb9ade](https://github.com/sile-typesetter/sile/commit/0fb9adefca3adf9ff8a56755e69474960792d85a)) +* **cli:** Allow multiple runtime SILE_PATH segments (backport from develop branch) ([e7c8fe2](https://github.com/sile-typesetter/sile/commit/e7c8fe219686aa327032154484bf78be86c0baaa)) + + +### Bug Fixes + +* **frames:** Update frame constraints with new frame IDs after \makecolumns ([b2d6b4f](https://github.com/sile-typesetter/sile/commit/b2d6b4f7b095d74f3d39123904495a8e024c0f05)) + ### [0.14.12](https://github.com/sile-typesetter/sile/compare/v0.14.11...v0.14.12) (2023-10-11) diff --git a/action.yml b/action.yml index a35fcf9bd..6b80884ca 100644 --- a/action.yml +++ b/action.yml @@ -7,7 +7,7 @@ inputs: default: "" runs: using: docker - image: docker://ghcr.io/sile-typesetter/sile:v0.14.12 + image: docker://ghcr.io/sile-typesetter/sile:v0.14.13 entrypoint: sh args: - -c diff --git a/classes/base.lua b/classes/base.lua index b06428202..0d469006a 100644 --- a/classes/base.lua +++ b/classes/base.lua @@ -79,7 +79,12 @@ end function class:setOptions (options) options = options or {} - options.papersize = options.papersize or "a4" + -- Classes that add options with dependencies should explicitly handle them, then exempt them from furthur processing. + -- The landscape option is handled explicitly before papersize, then the "rest" of options that are not interdependent. + self.options.landscape = SU.boolean(options.landscape, false) + options.landscape = nil + self.options.papersize = options.papersize or "a4" + options.papersize = nil for option, value in pairs(options) do self.options[option] = value end @@ -101,10 +106,16 @@ function class:declareOptions () end return self._name end) + self:declareOption("landscape", function(_, landscape) + if landscape then + self.landscape = landscape + end + return self.landscape + end) self:declareOption("papersize", function (_, size) if size then self.papersize = size - SILE.documentState.paperSize = SILE.papersize(size) + SILE.documentState.paperSize = SILE.papersize(size, self.options.landscape) SILE.documentState.orgPaperSize = SILE.documentState.paperSize SILE.newFrame({ id = "page", diff --git a/core/papersize.lua b/core/papersize.lua index 2b8a9d062..f1b9c4a04 100644 --- a/core/papersize.lua +++ b/core/papersize.lua @@ -63,16 +63,19 @@ local papersize = { } setmetatable(papersize, { - __call = function (self, size) + __call = function (self, size, landscape) + local geometry local _, _, x, y = string.find(size, "(.+)%s+x%s+(.+)") if x and y then - return { SILE.measurement(x):tonumber(), SILE.measurement(y):tonumber() } + geometry = { SILE.measurement(x):tonumber(), SILE.measurement(y):tonumber() } else - size = string.lower(size:gsub("[-%s]+", "")) - if self[size] then - return self[size] - end + local preset_name = string.lower(size:gsub("[-%s]+", "")) + geometry = self[preset_name] end + if SU.boolean(landscape) then + geometry[1], geometry[2] = geometry[2], geometry[1] + end + if geometry then return geometry end SU.error(string.format([[Unable to parse papersize '%s'. Custom sizes may be entered with 'papersize= x '. Predefined paper sizes include: %s]], diff --git a/documentation/c03-input.sil b/documentation/c03-input.sil index f41a7cbc5..3151e7f94 100644 --- a/documentation/c03-input.sil +++ b/documentation/c03-input.sil @@ -61,6 +61,14 @@ Once some of the basic document properties have been set up using these fixed si For example, once the paper size is set, percentage of page width (\code{\%pw}) and height(\code{\%ph}) become valid units. In Chapter 4 we will meet more of these relative units, and in Chapter 7 we will meet some other ways of specifying lengths to make them stretchable or shrinkable. +\subsection{Setting orientation as landscape} + +The orientation of the page is defined as "portrait" by default, but if you want to set it as landscape there is an option for that: + +\begin[type=autodoc:codeblock]{raw} +\begin[landscape=true]{document} +\end{raw} + \section{Ordinary text} On the whole, ordinary text isn’t particularly interesting—it’s just typeset. diff --git a/justenough/justenoughharfbuzz.c b/justenough/justenoughharfbuzz.c index a576da9c3..0da49f589 100644 --- a/justenough/justenoughharfbuzz.c +++ b/justenough/justenoughharfbuzz.c @@ -144,7 +144,7 @@ int shape (lua_State *L) { const char * lang = luaL_checkstring(L, 5); double point_size = luaL_checknumber(L, 6); const char * featurestring = luaL_checkstring(L, 7); - char * shaper_list_string = luaL_checkstring(L, 8); + char * shaper_list_string = (char *)luaL_checkstring(L, 8); const char * const* shaper_list = NULL; if (strlen(shaper_list_string) > 0) { shaper_list = (const char * const*)scan_shaper_list(shaper_list_string); diff --git a/justenough/justenoughlibtexpdf.c b/justenough/justenoughlibtexpdf.c index 0ef178f26..b31ee4a73 100644 --- a/justenough/justenoughlibtexpdf.c +++ b/justenough/justenoughlibtexpdf.c @@ -14,7 +14,7 @@ pdf_doc *p = NULL; double height = 0.0; double precision = 65536.0; -char* producer = "SILE"; +const char* producer = "SILE"; #define ASSERT_PDF_OPENED(p) \ if (!p) { \ @@ -24,10 +24,10 @@ char* producer = "SILE"; int pdf_init (lua_State *L) { pdf_rect mediabox; - const char* fn = luaL_checkstring(L, 1); + const char* fn = luaL_checkstring(L, 1); double w = luaL_checknumber(L, 2); height = luaL_checknumber(L, 3); - producer = luaL_checkstring(L, 4); + const char* producer = luaL_checkstring(L, 4); p = texpdf_open_document(fn, 0, w, height, 0,0,0); texpdf_init_device(p, 1/precision, 2, 0); diff --git a/package.json b/package.json index fd5b1eed1..043deba9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sile", - "version": "0.14.12", + "version": "0.14.13", "description": "The SILE Typesetter", "main": "sile", "scripts": { diff --git a/packages/cropmarks/init.lua b/packages/cropmarks/init.lua index 59b6b8f71..a3c5af14f 100644 --- a/packages/cropmarks/init.lua +++ b/packages/cropmarks/init.lua @@ -70,7 +70,8 @@ function package:registerCommands () self:registerCommand("crop:setup", function (options, _) local papersize = SU.required(options, "papersize", "setting up crop marks") - local size = SILE.papersize(papersize) + local landscape = SU.boolean(options.landscape, self.class.options.landscape) + local size = SILE.papersize(papersize, landscape) local oldsize = SILE.documentState.paperSize SILE.documentState.paperSize = size local offsetx = ( SILE.documentState.paperSize[1] - oldsize[1] ) /2 diff --git a/packages/frametricks/init.lua b/packages/frametricks/init.lua index bb4ecb59f..6b1ae6754 100644 --- a/packages/frametricks/init.lua +++ b/packages/frametricks/init.lua @@ -41,7 +41,7 @@ end local makecolumns = function (options) local cFrame = SILE.typesetter.frame - local cols = options.columns or 2 + local cols = options.columns local gutterWidth = options.gutter or "3%pw" local right = cFrame:right() local origId = cFrame.id @@ -174,7 +174,31 @@ function package:registerCommands () end, "Breaks the current frame in two vertically at the current location or at a point below the current location") self:registerCommand("makecolumns", function (options, _) + -- Set a default value for column count + options.columns = options.columns or 2 + local current_frame = SILE.typesetter.frame + local original_constraints = {} + -- Collect existing constraints that may need updating after makecolumns() changes them + for frameid in pairs(SILE.frames) do + if frameid ~= current_frame.id then + local frame = SILE.getFrame(frameid) + for method in pairs(frame.constraints) do + -- TODO: Remove the assumption about direction when makecolumns() takes into account frame advance direction + if method == "right" then + if frame[method](frame) == current_frame[method](current_frame) then + table.insert(original_constraints, { frame = frame, method = method }) + end + end + end + end + end makecolumns(options) + for _, info in ipairs(original_constraints) do + local frame, method = info.frame, info.method + local final_column_id = ("%s_col%d"):format(current_frame.id, options.columns-1) + local final_comumn_frame = SILE.getFrame(final_column_id) + frame:constrain(method, final_comumn_frame[method](final_comumn_frame)) + end end, "Split the current frame into multiple columns") self:registerCommand("breakframehorizontal", function (options, _) diff --git a/spec/measurements_spec.lua b/spec/measurements_spec.lua index 52d9b1966..e4b9eec16 100644 --- a/spec/measurements_spec.lua +++ b/spec/measurements_spec.lua @@ -2,7 +2,7 @@ SILE = require("core.sile") SU.warn = function () end describe("The papersize parser", function() - local parse = SILE.paperSizeParser + local parse = SILE.papersize it("should return the correct values for a6", function() local a6 = { 297.6377985, 419.52756359999995 } assert.is.same(parse("a6"), a6) @@ -14,6 +14,11 @@ describe("The papersize parser", function() assert.is.same(parse("2in x 4in"), size) assert.is.same(parse("144 x 288"), size) end) + it("should flip x and y page geometry for landscape mode", function() + local size = { 288, 144 } + assert.is.same(parse("2in x 4in", true), size) + assert.is.same(parse("144 x 288", true), size) + end) it("error if unable to parse", function() assert.has.errors(function () parse("notapaper") end) assert.has.errors(function () parse(nil) end) diff --git a/tests/landscape.expected b/tests/landscape.expected new file mode 100644 index 000000000..69035d1aa --- /dev/null +++ b/tests/landscape.expected @@ -0,0 +1,8 @@ +Set paper size 841.8897729 595.275597 +Begin page +Mx 418.5987 +My 553.7327 +Set font Gentium Plus;10;400;;normal;;;LTR +T 20 w=4.6924 (1) +End page +Finish diff --git a/tests/landscape.sil b/tests/landscape.sil new file mode 100644 index 000000000..5e3f9b645 --- /dev/null +++ b/tests/landscape.sil @@ -0,0 +1,2 @@ +\begin[landscape=true]{document} +\end{document} diff --git a/tests/makecolumns.expected b/tests/makecolumns.expected new file mode 100644 index 000000000..4e4cf097b --- /dev/null +++ b/tests/makecolumns.expected @@ -0,0 +1,8 @@ +Set paper size 419.5275636 595.275597 +Begin page +Mx 207.4176 +My 553.7327 +Set font Gentium Plus;10;400;;normal;;;LTR +T 20 w=4.6924 (1) +End page +Finish diff --git a/tests/makecolumns.sil b/tests/makecolumns.sil new file mode 100644 index 000000000..1617d0233 --- /dev/null +++ b/tests/makecolumns.sil @@ -0,0 +1,5 @@ +\begin[papersize=a5]{document} +\use[module=packages.frametricks] +\makecolumns[columns=4] +\showframe[id=all] +\end{document}