work
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 18 Aug 2024 17:39:53 +0000 (10:39 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 18 Aug 2024 17:39:53 +0000 (10:39 -0700)
rust/src/format.rs
rust/src/output/pivot/mod.rs

index 3612134a24ae6f34ca7c32d070e0b4aca5d644ce..0c5fca05bd02580bd4fb6a7715d6bd56026156bb 100644 (file)
@@ -3,6 +3,7 @@ use std::{
     ops::RangeInclusive,
 };
 
+use enum_map::{Enum, EnumMap};
 use thiserror::Error as ThisError;
 
 use crate::{
@@ -98,7 +99,7 @@ impl From<Format> for Category {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, Enum, PartialEq, Eq, Hash)]
 pub enum CC {
     A,
     B,
@@ -565,3 +566,52 @@ impl Display for UncheckedSpec {
         Ok(())
     }
 }
+
+pub struct Settings {
+    epoch: Option<i32>,
+
+    /// Either `b'.'` or `b','`.
+    decimal: char,
+
+    /// Format `F`, `E`, `COMMA`, and `DOT` with leading zero (e.g. `0.5`
+    /// instead of `.5`)?
+    include_leading_zero: bool,
+
+    /// Custom currency styles.
+    ccs: EnumMap<CC, NumberStyle>,
+}
+
+/// A numeric output style.  This can express numeric formats in
+/// [Category::Basic] and [Category::Custom].
+pub struct NumberStyle {
+    neg_prefix: Affix,
+    prefix: Affix,
+    suffix: Affix,
+    neg_suffix: Affix,
+
+    /// Decimal point: `'.'` or `','`.
+    decimal: char,
+
+    /// Grouping character: `'.'` or `','` or `None`.
+    grouping: Option<char>,
+
+    /// Format as `.5` or `0.5`?
+    include_leading_zero: bool,
+
+    /// An `Affix` may require more bytes than its display width; for example,
+    /// U+00A5 (¥) is 2 bytes in UTF-8 but occupies only one display column.
+    /// This member is the sum of the number of bytes required by all of the
+    /// `Affix` members in this struct, minus their display widths.  Thus, it
+    /// can be used to size memory allocations: for example, the formatted
+    /// result of `CCA20.5` requires no more than `(20 + extra_bytes)` bytes in
+    /// UTF-8.
+    extra_bytes: usize,
+}
+
+pub struct Affix {
+    /// String contents of affix.
+    s: String,
+
+    /// Display width in columns (see [unicode_width])
+    width: usize,
+}
index a46154a938ba65120806387cb2233c79472f1301..9336cc0bd47d4c04bdf5b201759e710fdfd7a13d 100644 (file)
 
 use std::{collections::HashMap, ops::Range, sync::Arc};
 
+use chrono::NaiveDateTime;
 use enum_map::{Enum, EnumMap};
 
-use crate::format::Spec;
+use crate::format::{Settings as FormatSettings, Spec};
 
 /// Areas of a pivot table for styling purposes.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Enum, PartialEq, Eq)]
 pub enum Area {
     Title,
     Caption,
@@ -82,6 +83,7 @@ pub enum Area {
 }
 
 /// Table borders for styling purposes.
+#[derive(Debug, Enum)]
 pub enum Border {
     Title,
     OuterFrame(BoxBorder),
@@ -93,6 +95,7 @@ pub enum Border {
 }
 
 /// The borders on a box.
+#[derive(Debug, Enum)]
 pub enum BoxBorder {
     Left,
     Top,
@@ -101,6 +104,7 @@ pub enum BoxBorder {
 }
 
 /// Borders between rows and columns.
+#[derive(Debug, Enum)]
 pub enum RowColBorder {
     RowHorz,
     RowVert,
@@ -125,10 +129,10 @@ pub struct Sizing {
 }
 
 #[derive(Enum)]
-pub enum Axis {
-    Layer,
-    Row,
-    Column,
+pub enum Axis3 {
+    X,
+    Y,
+    Z,
 }
 
 /// An axis within a pivot table.
@@ -156,7 +160,7 @@ pub struct TableAxis {
 /// If a dimension contains no categories, then its table cannot contain any
 /// data.)
 pub struct Dimension {
-    axis_type: Axis,
+    axis_type: Axis3,
     level: usize,
 
     top_index: usize,
@@ -249,7 +253,119 @@ struct Look {
 
     /// Where to put the footnote markers.
     footnote_marker_position: FootnoteMarkerPosition,
-    // XXX and so on
+
+    /// Styles for areas of the pivot table.
+    areas: EnumMap<Area, AreaStyle>,
+
+    /// Styles for borders in the pivot table.
+    borders: EnumMap<Border, BorderStyle>,
+
+    print_all_layers: bool,
+
+    paginate_layers: bool,
+
+    shrink_to_fit: EnumMap<Axis2, bool>,
+
+    top_continuation: bool,
+
+    bottom_continuation: bool,
+
+    continuation: Option<String>,
+
+    n_orphan_lines: usize,
+}
+
+pub struct AreaStyle {
+    cell_style: CellStyle,
+    font_style: FontStyle,
+}
+
+pub struct CellStyle {
+    horz_align: HorzAlign,
+    vert_align: VertAlign,
+
+    /// Margins in 1/96" units.
+    ///
+    /// `margins[Axis2::X][0]` is the left margin.
+    /// `margins[Axis2::X][1]` is the right margin.
+    /// `margins[Axis2::Y][0]` is the top margin.
+    /// `margins[Axis2::Y][1]` is the bottom margin.
+    margins: EnumMap<Axis2, [i32; 2]>,
+}
+
+pub enum HorzAlign {
+    /// Right aligned.
+    Right,
+
+    /// Left aligned.
+    Left,
+
+    /// Centered.
+    Center,
+
+    /// Align strings to the left, other formats to the right.
+    Mixed,
+
+    /// Align the decimal point at the specified position.
+    Decimal {
+        /// Decimal offset from the right side of the cell, in 1/96" units.
+        offset: f64,
+
+        /// Decimal character: either `b'.'` or `b','`.
+        c: char,
+    },
+}
+
+pub enum VertAlign {
+    /// Top alignment.
+    Top,
+
+    /// Centered,
+    Center,
+
+    /// Bottom alignment.
+    Bottom,
+}
+
+pub struct FontStyle {
+    bold: bool,
+    italic: bool,
+    underline: bool,
+    markup: bool,
+    font: String,
+    fg: [Color; 2],
+    bg: [Color; 2],
+
+    /// In 1/72" units.
+    size: i32,
+}
+
+pub struct Color {
+    alpha: u8,
+    r: u8,
+    g: u8,
+    b: u8,
+}
+
+pub struct BorderStyle {
+    stroke: Stroke,
+    color: Color,
+}
+
+pub enum Stroke {
+    None,
+    Solid,
+    Dashed,
+    Thick,
+    Thin,
+    Double,
+}
+
+/// An axis of a flat table.
+#[derive(Debug, Enum)]
+pub enum Axis2 {
+    X,
+    Y,
 }
 
 pub enum FootnoteMarkerType {
@@ -300,7 +416,9 @@ pub struct Table {
     /// Row sizing and page breaks.
     row_sizing: Sizing,
 
-    // XXX format settings
+    /// Format settings.
+    settings: FormatSettings,
+
     /// Numeric grouping character (usually `.` or `,`).
     grouping: char,
 
@@ -312,7 +430,7 @@ pub struct Table {
     locale: Option<String>,
     dataset: Option<String>,
     datafile: Option<String>,
-    //XXX date
+    date: Option<NaiveDateTime>,
     footnotes: Vec<Footnote>,
     title: Value,
     subtype: Value,
@@ -320,7 +438,7 @@ pub struct Table {
     caption: Value,
     notes: Option<String>,
     dimensions: Vec<Dimension>,
-    axes: EnumMap<Axis, TableAxis>,
+    axes: EnumMap<Axis3, TableAxis>,
     cells: HashMap<u64, Value>,
 }
 
@@ -385,5 +503,8 @@ pub enum ValueInner {
 }
 
 pub struct ValueStyle {
-    // XXX
+    font_style: FontStyle,
+    cell_style: CellStyle,
+    subscripts: Vec<String>,
+    footnote_indexes: Vec<usize>
 }