max / quasi
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
1 file changed,
+48 insertions,
-43 deletions
| @@ -40,8 +40,6 @@ | |||
| 40 | 40 | Table, | |
| 41 | 41 | /// One column: its body says how it narrows, and it emits nothing. | |
| 42 | 42 | Column, | |
| 43 | - | /// One row of a table: its members are its cells, by position. | |
| 44 | - | Cells, | |
| 45 | 43 | /// One cell: its body says what opening it does. | |
| 46 | 44 | Cell, | |
| 47 | 45 | /// One node member: its body says what it is told afterwards. | |
| @@ -330,7 +328,7 @@ | |||
| 330 | 328 | } | |
| 331 | 329 | }, | |
| 332 | 330 | "Row" => match only { | |
| 333 | - | Emission::Row { primary, body } => row(primary, body)?, | |
| 331 | + | Emission::Row { primary, body } => row(Some(primary), body)?, | |
| 334 | 332 | other => { | |
| 335 | 333 | return Err(syn::Error::new( | |
| 336 | 334 | emission_span(other), | |
| @@ -650,7 +648,7 @@ | |||
| 650 | 648 | "a document holds regions: write `region <name> as <kind> { .. }` \ | |
| 651 | 649 | or `include <shape>;`", | |
| 652 | 650 | )), | |
| 653 | - | (Container::Cells | Container::Cell | Container::Row, Emission::Activate(action)) => { | |
| 651 | + | (Container::Cell | Container::Row, Emission::Activate(action)) => { | |
| 654 | 652 | Ok((self::action(action)?, quote!(.activate(#held)))) | |
| 655 | 653 | } | |
| 656 | 654 | (Container::Row, Emission::Act { .. }) => Ok((act(emission)?, quote!(.act(#held)))), | |
| @@ -681,11 +679,36 @@ | |||
| 681 | 679 | let part = variant(priority, "RowPart")?; | |
| 682 | 680 | Ok((node(inner)?, quote!(.part(#part, #held)))) | |
| 683 | 681 | } | |
| 682 | + | // A cell names its column instead of taking a role, and that is the | |
| 683 | + | // whole of what a table row spells differently. One container since the | |
| 684 | + | // 2026-09-05 collapse, so this sits beside `beside` rather than in a | |
| 685 | + | // second settings table. | |
| 686 | + | ( | |
| 687 | + | Container::Row, | |
| 688 | + | Emission::Cell { | |
| 689 | + | column, | |
| 690 | + | value, | |
| 691 | + | body, | |
| 692 | + | }, | |
| 693 | + | ) => { | |
| 694 | + | let built = cell(value, body)?; | |
| 695 | + | Ok(match column { | |
| 696 | + | Some(column) => { | |
| 697 | + | let column = arg(column)?; | |
| 698 | + | (built, quote!(.at(#column, #held))) | |
| 699 | + | } | |
| 700 | + | None => (built, quote!(.cell(#held))), | |
| 701 | + | }) | |
| 702 | + | } | |
| 703 | + | // One message, because there is one container. A row places its content | |
| 704 | + | // by key and the two spellings are the two kinds of key: `beside <part>` | |
| 705 | + | // names a role of the default column set, `cell at <column>` names a | |
| 706 | + | // declared column. | |
| 684 | 707 | (Container::Row, other) => Err(syn::Error::new( | |
| 685 | 708 | emission_span(other), | |
| 686 | - | "a row holds controls, places its parts and says what opening it does: write \ | |
| 687 | - | `act <label> to <action>;`, `include <shape>;`, `beside <part> <emission>` \ | |
| 688 | - | or `activate to <action>;`", | |
| 709 | + | "a row holds controls, places its content and says what opening it does: write \ | |
| 710 | + | `act <label> to <action>;`, `include <shape>;`, `beside <part> <emission>`, \ | |
| 711 | + | `cell [at <column>] <value>;` or `activate to <action>;`", | |
| 689 | 712 | )), | |
| 690 | 713 | (Container::Image, other) => Err(syn::Error::new( | |
| 691 | 714 | emission_span(other), | |
| @@ -743,27 +766,6 @@ | |||
| 743 | 766 | "a table holds columns and rows: write `column <name>;`, `cells { .. }` \ | |
| 744 | 767 | or `include <shape>;`", | |
| 745 | 768 | )), | |
| 746 | - | ( | |
| 747 | - | Container::Cells, | |
| 748 | - | Emission::Cell { | |
| 749 | - | column, | |
| 750 | - | value, | |
| 751 | - | body, | |
| 752 | - | }, | |
| 753 | - | ) => { | |
| 754 | - | let built = cell(value, body)?; | |
| 755 | - | Ok(match column { | |
| 756 | - | Some(column) => { | |
| 757 | - | let column = arg(column)?; | |
| 758 | - | (built, quote!(.at(#column, #held))) | |
| 759 | - | } | |
| 760 | - | None => (built, quote!(.cell(#held))), | |
| 761 | - | }) | |
| 762 | - | } | |
| 763 | - | (Container::Cells, other) => Err(syn::Error::new( | |
| 764 | - | emission_span(other), | |
| 765 | - | "a row of a table holds cells: write `cell <value>;`", | |
| 766 | - | )), | |
| 767 | 769 | (Container::Cell, Emission::Act { .. }) => Ok((act(emission)?, quote!(.act(#held)))), | |
| 768 | 770 | // A control another shape built, as a row takes one. `item_files`'s | |
| 769 | 771 | // acts column holds a Download written here and a Delete that is | |
| @@ -1572,7 +1574,7 @@ | |||
| 1572 | 1574 | /// for the same reason, and this is the list saying it the same way. | |
| 1573 | 1575 | fn list_row(emission: &Emission) -> Result<TokenStream> { | |
| 1574 | 1576 | match emission { | |
| 1575 | - | Emission::Row { primary, body } => row(primary, body), | |
| 1577 | + | Emission::Row { primary, body } => row(Some(primary), body), | |
| 1576 | 1578 | Emission::Include(supplier) => { | |
| 1577 | 1579 | let supplier = hole(supplier)?; | |
| 1578 | 1580 | Ok(quote!(::std::convert::Into::into(#supplier))) | |
| @@ -1610,13 +1612,9 @@ | |||
| 1610 | 1612 | ) | |
| 1611 | 1613 | } | |
| 1612 | 1614 | ||
| 1613 | - | /// One row of a table, by position. | |
| 1615 | + | /// One row of a table, by position. `row` with no primary. | |
| 1614 | 1616 | fn cells(body: &[Item]) -> Result<TokenStream> { | |
| 1615 | - | accrete( | |
| 1616 | - | body, | |
| 1617 | - | Container::Cells, | |
| 1618 | - | "e!(<::quasi_router::screen::Cells as ::std::default::Default>::default()), | |
| 1619 | - | ) | |
| 1617 | + | row(None, body) | |
| 1620 | 1618 | } | |
| 1621 | 1619 | ||
| 1622 | 1620 | /// One cell: what it says, what it holds, and what opening it does. | |
| @@ -1629,14 +1627,21 @@ | |||
| 1629 | 1627 | ) | |
| 1630 | 1628 | } | |
| 1631 | 1629 | ||
| 1632 | - | /// One row of a list: what it says, and what it offers. | |
| 1633 | - | fn row(primary: &Arg, body: &[Item]) -> Result<TokenStream> { | |
| 1634 | - | let primary = arg(primary)?; | |
| 1635 | - | accrete( | |
| 1636 | - | body, | |
| 1637 | - | Container::Row, | |
| 1638 | - | "e!(::quasi_router::Row::new(#primary)), | |
| 1639 | - | ) | |
| 1630 | + | /// One row: what it says, what it holds, and what it offers. | |
| 1631 | + | /// | |
| 1632 | + | /// One function since the 2026-09-05 collapse. `row "x" { .. }` and `cells { | |
| 1633 | + | /// .. }` were two builders onto what is now one type, differing only in whether | |
| 1634 | + | /// a primary was named: a list row opens with its primary text and a table row | |
| 1635 | + | /// opens empty and fills by key. That is an argument, not a second function. | |
| 1636 | + | fn row(primary: Option<&Arg>, body: &[Item]) -> Result<TokenStream> { | |
| 1637 | + | let base = match primary { | |
| 1638 | + | Some(primary) => { | |
| 1639 | + | let primary = arg(primary)?; | |
| 1640 | + | quote!(::quasi_router::Row::new(#primary)) | |
| 1641 | + | } | |
| 1642 | + | None => quote!(<::quasi_router::Row as ::std::default::Default>::default()), | |
| 1643 | + | }; | |
| 1644 | + | accrete(body, Container::Row, &base) | |
| 1640 | 1645 | } | |
| 1641 | 1646 | ||
| 1642 | 1647 | /// One control: what it is called, what it does, and what it is like. |