<commit_before>{-# LANGUAGE GADTs #-}

-- | A 'Symbol' is actually going to be a graphical description of what
-- gets rendered as a (unique) symbol.  This is actually NOT based on
-- semantics at all, but just a description of how things look.

module Language.Drasil.Symbol where

import Language.Drasil.Unicode 
import Data.Char (toLower)

-- | Decorations on symbols/characters such as hats or Vector representations
-- (bolding/etc)
data Decoration = Hat | Vector | Prime deriving (Eq, Ord)

-- | Symbols can be:
-- - atomic (strings such as "A" or "max" that represent a single idea)
-- - special characters (ex. unicode)
-- - Greek characters
-- - Decorated symbols
-- - Concatenations of symbols, including subscripts and superscripts
-- - empty! (this is to give this a monoid-like flavour)
data Symbol where
  Atomic   :: String -> Symbol
  Special  :: Special -> Symbol
  Greek    :: Greek -> Symbol
  Atop  :: Decoration -> Symbol -> Symbol
  Corners  :: [Symbol] -> [Symbol] -> [Symbol] -> [Symbol] -> Symbol -> Symbol
            --upleft  -> lowleft  -> upright  -> lowright -> base   -> out
            -- [1] -> [2] -> [3] -> [4] -> [5] -> out
            --  Visually:  [1]   [3]
            --    (out)       [5]
            --             [2]   [4]
  Concat :: [ Symbol ]  -> Symbol
            -- [s1, s2] -> s1s2
  Empty  :: Symbol
  deriving Eq

instance Monoid Symbol where
  mempty = Empty
  mappend a b = Concat [a , b]

--FIXME? The exact ordering we want may need to be updated, or should we
--  allow custom?  
instance Ord Symbol where
  compare (Concat (x:[]))       (Concat (y:[]))        = compare x y
  compare (Concat ((Greek Delta):xs))                b = compare (Concat xs) b 
  compare a                (Concat ((Greek Delta):ys)) = compare a           (Concat ys)
  compare (Concat (x:xs))       (Concat (x':ys))       = --The above two lines ensure symbols like "x" and "delta x" stay together
    case compare x x' of
      EQ -> compare xs ys
      other -> other
  compare (Concat a)             b                     = compare a [b]
  compare b                      (Concat a)            = compare [b] a
  compare (Corners _ _ ur lr b) (Corners _ _ u' l' b') = 
    case compare b b' of
      EQ -> case compare lr l' of
            EQ -> compare ur u'
            other -> other
      other -> other
  compare (Corners _ _ _ _ a)    b                     = compare a b
  compare b                      (Corners _ _ _ _ a)   = compare b a
  compare (Atop d1 a)           (Atop d2 a')           = 
    case compare a a' of
      EQ -> compare d1 d2<commit_msg>no real need for GADT here, so use 'normal' syntax.<commit_after>-- | A 'Symbol' is actually going to be a graphical description of what
-- gets rendered as a (unique) symbol.  This is actually NOT based on
-- semantics at all, but just a description of how things look.

module Language.Drasil.Symbol where

import Language.Drasil.Unicode 
import Data.Char (toLower)

-- | Decorations on symbols/characters such as hats or Vector representations
-- (bolding/etc)
data Decoration = Hat | Vector | Prime deriving (Eq, Ord)

-- | Symbols can be:
-- - atomic (strings such as "A" or "max" that represent a single idea)
-- - special characters (ex. unicode)
-- - Greek characters
-- - Decorated symbols
-- - Concatenations of symbols, including subscripts and superscripts
-- - empty! (this is to give this a monoid-like flavour)
data Symbol =
    Atomic  String
  | Special Special
  | Greek   Greek
  | Atop    Decoration Symbol
  | Corners [Symbol] [Symbol] [Symbol] [Symbol] Symbol
          -- upleft   lowleft  upright  lowright base
          -- [1]      [2]      [3]      [4]      [5]
          --  Visually:  [1]   [3]
          --    (out)       [5]
          --             [2]   [4]
  | Concat [Symbol]
            -- [s1, s2] -> s1s2
  | Empty
  deriving Eq

instance Monoid Symbol where
  mempty = Empty
  mappend a b = Concat [a , b]

--FIXME? The exact ordering we want may need to be updated, or should we
--  allow custom?  
instance Ord Symbol where
  compare (Concat (x:[]))       (Concat (y:[]))        = compare x y
  compare (Concat ((Greek Delta):xs))                b = compare (Concat xs) b 
  compare a                (Concat ((Greek Delta):ys)) = compare a           (Concat ys)
  compare (Concat (x:xs))       (Concat (x':ys))       = --The above two lines ensure symbols like "x" and "delta x" stay together
    case compare x x' of
      EQ -> compare xs ys
      other -> other
  compare (Concat a)             b                     = compare a [b]
  compare b                      (Concat a)            = compare [b] a
  compare (Corners _ _ ur lr b) (Corners _ _ u' l' b') = 
    case compare b b' of
      EQ -> case compare lr l' of
            EQ -> compare ur u'
            other -> other
      other -> other
  compare (Corners _ _ _ _ a)    b                     = compare a b
  compare b                      (Corners _ _ _ _ a)   = compare b a
  compare (Atop d1 a)           (Atop d2 a')           = 
    case compare a a' of
      EQ -> compare d1 d2
{'fraction_non_alphanumeric': 0.10814524043179588, 'fraction_numerical': 0.0070657507360157015, 'mean_word_length': 1.8123620309050772, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6620883', 'n_tokens_mistral': 1586, 'n_tokens_neox': 1529, 'n_words': 624}