http://mathling.com/type/mask  library module

http://mathling.com/type/mask


Constructors and accessors for masks: masking objects

Copyright© Mary Holstege 2020-2023
CC-BY (https://creativecommons.org/licenses/by/4.0/)

June 2022
Status: New

Imports

http://mathling.com/core/utilities
import module namespace util="http://mathling.com/core/utilities"
       at "../core/utilities.xqy"
http://mathling.com/core/config
import module namespace config="http://mathling.com/core/config"
       at "../core/config.xqy"
http://mathling.com/core/errors
import module namespace errors="http://mathling.com/core/errors"
       at "../core/errors.xqy"
http://mathling.com/geometric/point
import module namespace point="http://mathling.com/geometric/point"
       at "../geo/point.xqy"

Variables

Variable: $RESERVED as xs:string*

Functions

Function: mask
declare function mask($id as xs:string, $body as item()*, $properties as map(xs:string,item()*)) as map(xs:string,item()*)


mask()
Make a mask
$id: the mask ID
$body: contents of the mask
$properties: additional properties

Params
  • id as xs:string
  • body as item()*
  • properties as map(xs:string,item()*)
Returns
  • map(xs:string,item()*)
declare function this:mask(
  $id as xs:string,
  $body as item()*,
  $properties as map(xs:string,item()*)
) as map(xs:string,item()*)
{
  util:merge-into($properties,
    map {
      "kind": "mask",
      "id": $id,
      "body": $body
    }
  )
}

Function: mask
declare function mask($id as xs:string, $body as item()*) as map(xs:string,item()*)


mask()
Make a mask
$body: contents of the mask

Params
  • id as xs:string
  • body as item()*
Returns
  • map(xs:string,item()*)
declare function this:mask(
  $id as xs:string,
  $body as item()*
) as map(xs:string,item()*)
{
  map {
    "kind": "mask",
    "id": $id,
    "body": $body
  }
}

Function: kind
declare function kind($mask as map(xs:string,item()*)) as xs:string


kind()
Accessor for the kind of data this is; for debugging and polymorphic functions

Params
  • mask as map(xs:string,item()*): the mask
Returns
  • xs:string
declare function this:kind($mask as map(xs:string,item()*)) as xs:string
{
  $mask("kind")
}

Function: body
declare function body($mask as map(xs:string,item()*)) as item()*


body()
Get the contents of the mask

Params
  • mask as map(xs:string,item()*): the mask
Returns
  • item()*
declare function this:body($mask as map(xs:string,item()*)) as item()*
{
  $mask("body")
}

Function: id
declare function id($mask as map(xs:string,item()*)) as xs:string


id()
Get the unique id of the mask

Params
  • mask as map(xs:string,item()*): the mask
Returns
  • xs:string
declare function this:id($mask as map(xs:string,item()*)) as xs:string
{
  $mask("id")
}

Function: ref
declare function ref($mask as map(xs:string,item()*)) as xs:string


ref()
Get a URL reference to the mask.

Params
  • mask as map(xs:string,item()*): the mask
Returns
  • xs:string
declare function this:ref($mask as map(xs:string,item()*)) as xs:string
{
  "url(#"||this:id($mask)||")"
}

Function: body
declare function body($mask as map(xs:string,item()*), $body as item()*) as map(xs:string,item()*)


body()
Set the contents of the mask, returning the new mask

Params
  • mask as map(xs:string,item()*): the mask
  • body as item()*: the contents
Returns
  • map(xs:string,item()*)
declare function this:body($mask as map(xs:string,item()*), $body as item()*) as map(xs:string,item()*)
{
  $mask=>map:put("body", $body)
}

Function: id
declare function id($mask as map(xs:string,item()*), $id as xs:string) as map(xs:string,item()*)


id()
Set the id of the mask, returning the new mask

Params
  • mask as map(xs:string,item()*): the mask
  • id as xs:string: the id
Returns
  • map(xs:string,item()*)
declare function this:id($mask as map(xs:string,item()*), $id as xs:string) as map(xs:string,item()*)
{
  $mask=>map:put("id", $id)
}

Function: property-map
declare function property-map($mask as map(xs:string,item()*)) as map(xs:string,item()*)

Params
  • mask as map(xs:string,item()*)
Returns
  • map(xs:string,item()*)
declare function this:property-map($mask as map(xs:string,item()*)) as map(xs:string,item()*)
{
  switch($mask=>map:get("kind")) 
  case "mask" return util:exclude($mask,$this:RESERVED)
  default return map {}
}

Function: properties
declare function properties($mask as item()) as xs:string*

Params
  • mask as item()
Returns
  • xs:string*
declare function this:properties($mask as item()) as xs:string*
{
  switch($mask=>map:get("kind"))
  case "mask" return ($mask=>map:keys())[not(. = $this:RESERVED)]
  default return ()
}

Function: with-properties
declare function with-properties($mask as item(), $properties as map(xs:string,item()*)) as map(xs:string,item()*)

Params
  • mask as item()
  • properties as map(xs:string,item()*)
Returns
  • map(xs:string,item()*)
declare function this:with-properties($mask as item(), $properties as map(xs:string,item()*)) as map(xs:string,item()*)
{
  util:merge-into($mask,
    switch($mask=>map:get("kind"))
    case "mask" return util:exclude($properties,$this:RESERVED)
    default return map {}
  )
}

Function: draw
declare function draw($item as map(xs:string,item()*), $properties as map(xs:string,item()*), $drawing as map(xs:string,function(*)?)) as item()*

Params
  • item as map(xs:string,item()*)
  • properties as map(xs:string,item()*)
  • drawing as map(xs:string,function(*)?)
Returns
  • item()*
declare function this:draw(
  $item as map(xs:string,item()*),
  $properties as map(xs:string,item()*),
  $drawing as map(xs:string,function(*)?)
) as item()*
{
  $this:draw-impl($item, $properties, $drawing)
}

Original Source Code

xquery version "3.1";
(:~
 : Constructors and accessors for masks: masking objects
 :
 : Copyright© Mary Holstege 2020-2023
 : CC-BY (https://creativecommons.org/licenses/by/4.0/)
 : @since June 2022
 : @custom:Status New
 :)
module namespace this="http://mathling.com/type/mask"; 

import module namespace config="http://mathling.com/core/config"
       at "../core/config.xqy";
import module namespace errors="http://mathling.com/core/errors"
       at "../core/errors.xqy";
import module namespace point="http://mathling.com/geometric/point"
       at "../geo/point.xqy";
import module namespace util="http://mathling.com/core/utilities"
       at "../core/utilities.xqy";
  
declare namespace art="http://mathling.com/art";
declare namespace svg="http://www.w3.org/2000/svg";
declare namespace map="http://www.w3.org/2005/xpath-functions/map";

(:======================================================================
 : Basic constructors
 :======================================================================:)

declare variable $this:RESERVED as xs:string* := ("kind", "body", "id");

(:~
 : mask()
 : Make a mask 
 :   $id: the mask ID
 :   $body: contents of the mask
 :   $properties: additional properties
 :)
declare function this:mask(
  $id as xs:string,
  $body as item()*,
  $properties as map(xs:string,item()*)
) as map(xs:string,item()*)
{
  util:merge-into($properties,
    map {
      "kind": "mask",
      "id": $id,
      "body": $body
    }
  )
};


(:~
 : mask()
 : Make a mask
 :   $body: contents of the mask
 :)
declare function this:mask(
  $id as xs:string,
  $body as item()*
) as map(xs:string,item()*)
{
  map {
    "kind": "mask",
    "id": $id,
    "body": $body
  }
};

(:======================================================================
 : Accessors
 :======================================================================:)

(:~ 
 : kind()
 : Accessor for the kind of data this is; for debugging and polymorphic functions
 :
 : @param $mask: the mask
 :)
declare function this:kind($mask as map(xs:string,item()*)) as xs:string
{
  $mask("kind")
};

(:~
 : body()
 : Get the contents of the mask
 : 
 : @param $mask: the mask
 :)
declare function this:body($mask as map(xs:string,item()*)) as item()*
{
  $mask("body")
};

(:~
 : id()
 : Get the unique id of the mask
 : 
 : @param $mask: the mask
 :)
declare function this:id($mask as map(xs:string,item()*)) as xs:string
{
  $mask("id")
};

(:~
 : ref()
 : Get a URL reference to the mask.
 :
 : @param $mask: the mask
 :)
declare function this:ref($mask as map(xs:string,item()*)) as xs:string
{
  "url(#"||this:id($mask)||")"
};

(:======================================================================
 : Setters
 :======================================================================:)

(:~
 : body()
 : Set the contents of the mask, returning the new mask
 : 
 : @param $mask: the mask
 : @param $body: the contents
 :)
declare function this:body($mask as map(xs:string,item()*), $body as item()*) as map(xs:string,item()*)
{
  $mask=>map:put("body", $body)
};

(:~
 : id()
 : Set the id of the mask, returning the new mask
 : 
 : @param $mask: the mask
 : @param $id: the id
 :)
declare function this:id($mask as map(xs:string,item()*), $id as xs:string) as map(xs:string,item()*)
{
  $mask=>map:put("id", $id)
};


(:======================================================================
 : Property manipulation and access
 :======================================================================:)

declare function this:property-map($mask as map(xs:string,item()*)) as map(xs:string,item()*)
{
  switch($mask=>map:get("kind")) 
  case "mask" return util:exclude($mask,$this:RESERVED)
  default return map {}
};

declare function this:properties($mask as item()) as xs:string*
{
  switch($mask=>map:get("kind"))
  case "mask" return ($mask=>map:keys())[not(. = $this:RESERVED)]
  default return ()
};

declare function this:with-properties($mask as item(), $properties as map(xs:string,item()*)) as map(xs:string,item()*)
{
  util:merge-into($mask,
    switch($mask=>map:get("kind"))
    case "mask" return util:exclude($properties,$this:RESERVED)
    default return map {}
  )
};

declare %private variable $this:draw-impl as function(*) :=
  if ($config:DRAWING-METHOD="art") then (
    function(
      $item as map(xs:string,item()*),
      $properties as map(xs:string,item()*),
      $drawing as map(xs:string,function(*)?)
    ) as item()* {
      let $style-properties := util:merge-into(($properties, this:property-map($item)))
      return (
        <art:mask id="{this:id($item)}">{
$drawing("draw:draw")(this:body($item), $style-properties, $drawing)
        }</art:mask>
      )
    }
  ) else (
    function(
      $item as map(xs:string,item()*),
      $properties as map(xs:string,item()*),
      $drawing as map(xs:string,function(*)?)
    ) as item()* {
      let $style-properties := util:merge-into(($drawing("draw:svg-style")($properties), $drawing("draw:svg-style")(this:property-map($item))))
      return (
        <svg:defs>
          <svg:mask id="{this:id($item)}">{
            $drawing("draw:draw")(this:body($item), $style-properties, $drawing)
          }</svg:mask>
        </svg:defs>
      )
    }
  )
;

declare function this:draw(
  $item as map(xs:string,item()*),
  $properties as map(xs:string,item()*),
  $drawing as map(xs:string,function(*)?)
) as item()*
{
  $this:draw-impl($item, $properties, $drawing)
};