Layout: inside/outside floats swap sides on even pages; Page Setup shows mirror margins (#1181) (#1239)

* Layout: inside/outside floats swap sides on even pages; Page Setup shows mirror margins (#1181)

Floats aligned inside or outside, or placed relative to the inside or
outside margin, were always put as on an odd page, so shapes Word puts
in a book's outside margin all came out on the right. They now follow
the page they're on (ECMA-376 ST_AlignH, ST_RelFromH): on an even page
the inside is the right side. Floating tables (w:tblpXSpec) too.

With mirrored margins, even pages are laid out as odd ones and then
shifted; float positions now allow for that shift, so floats placed
from the page edge stay put (the "known limit" in #452) and the left
and right margin areas are each page's own.

Mirrored margins read from a file were invisible in the UI: the Margins
menu ticks Mirrored when they're on, and Page Setup gets a Mirror
margins check box (labelling the margins Inside and Outside), applied
through a new `mirror` param of layout.margins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n: Mirror margins in every catalog

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: lloyd <lloyd@stackworx.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
LloydNicholson
2026-10-14 18:57:44 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 lloyd Brandon Thomas
parent cf140ae600
commit e0a1346590
27 changed files with 286 additions and 47 deletions
+5 -4
View File
@@ -12,7 +12,7 @@ use crate::{CmdError, CmdResult, CommandSpec, Selection, Session, p};
pub fn specs() -> Vec<CommandSpec> {
vec![
CommandSpec::new("layout.margins", "Margins", "Layout › Page Setup", margins).params(
r#"{"preset"?: "normal|narrow|moderate|wide|mirrored|office2003", "top"?: pt, "bottom"?: pt, "left"?: pt, "right"?: pt, "gutter"?: pt}"#,
r#"{"preset"?: "normal|narrow|moderate|wide|mirrored|office2003", "top"?: pt, "bottom"?: pt, "left"?: pt, "right"?: pt, "gutter"?: pt, "mirror"?: bool}"#,
),
CommandSpec::new("layout.orientation", "Orientation", "Layout › Page Setup", |s, v| {
let land = match p::str(v, "value") {
@@ -396,9 +396,10 @@ fn margins(s: &mut Session, v: &Value) -> CmdResult {
if !margins_fit((cur.page_w, cur.page_h), (t, b, l, r), gutter.unwrap_or(cur.gutter)) {
return Err(CmdError::Params("margins leave no room for text".into()));
}
// A preset picks mirrored or not; plain numbers (a ruler drag, an agent) keep the setting.
if preset.is_some() {
s.doc.settings.mirror_margins = preset == Some("mirrored");
// A preset picks mirrored or not, as does `mirror` (Page Setup's Multiple pages); plain numbers
// alone (a ruler drag, an agent) keep the setting.
if let Some(on) = p::bool(v, "mirror").or(preset.map(|k| k == "mirrored")) {
s.doc.settings.mirror_margins = on;
}
with_sect(s, |x| {
x.margin_top = t.max(0.0);