{
  tangle(object)::
    {
      [std.strReplace(object['$id'], 'https://picc.app/', '')]: object,
    },

  weave(object):: {
    [std.strReplace(object['$id'], 'https://picc.app/schemata', 'doc_src/reference') + '.md']:
      |||
        # %(title)s

        `[generated]`

        ID: `%(uri)s`

        %(description)s

        ## Type - `%(type)s`

        %(type_docs)s
      ||| % (object + { type_docs: weave_type(object), uri:object['$id'] }),
  },

  local weave_type(object) =
    if get_type(object) == 'oneOf' then
      weave_one_of_type(object)
    else if get_type(object) == 'ref' then
      weave_ref(object)
    else if get_type(object) == 'string' then
      weave_string_type(object)
    else if get_type(object) == 'number' then
      weave_number_type(object)
    else if get_type(object) == 'object' then
      weave_object_type(object)
    else if get_type(object) == 'array' then
      weave_array_type(object)
    else if get_type(object) == 'any' then
      ''
    else
      error 'Unknown schema type',

  // Weave functions for `string` type schemas.
  local string_constraints = ['minLength', 'maxLength', 'pattern'],
  local weave_string_type(object) =
    |||
      | Constraint | |
      |-|-|
    ||| +
    std.join('', [
      (if std.objectHas(object, constraint) then |||
         | `%(constraint)s` | %(constraint_value)s |
       ||| % {
         constraint: constraint,
         constraint_value: if std.type(object[constraint]) == 'string' then
           std.format('`%s`', object[constraint])
         else
           object[constraint],
       })
      for constraint in string_constraints
    ]),

  // Weave functions for `number` type schemas
  local number_constraits = ['minimum', 'maximum'],
  local weave_number_type(object) =
  |||
      | Constraint | |
      |-|-|
    ||| +
    std.join('', [
      (if std.objectHas(object, constraint) then |||
         | `%(constraint)s` | %(constraint_value)s |
       ||| % {
         constraint: constraint,
         constraint_value: if std.type(object[constraint]) == 'string' then
           std.format('`%s`', object[constraint])
         else
           object[constraint],
       })
      for constraint in number_constraits
    ]),

  // Weave fuctions for `object` type schemas
  local weave_object_type(object) =
    std.join('', [
      if !std.objectHas(object.properties[property], '$ref') then
        |||
          
          ---

          #### **%(property)s** - `%(property_type)s` %(property_required)s

          %(property_description)s

          %(property_type_docs)s
        ||| % {
          property: property,
          property_required: if std.setMember(property, std.set(object.required)) then '- *required*' else '',
          property_description: object.properties[property].description,
          property_type: get_type(object.properties[property]),
          property_type_docs: if get_type(object.properties[property]) != 'object' then 
          weave_type(object.properties[property])
          else std.join("\n", [
            std.format("> %s", line) for line in std.split(weave_type(object.properties[property]), "\n")]),
        }
      else
        |||
          #### %(property_required)s%(property)s%(property_required)s - Ref

          See %(property_ref)s
        ||| % {
          property: property,
          property_required: if std.setMember(property, object.required) then '**' else '',
          property_ref: object.properties[property]['$ref'],
        }
      for property in std.objectFields(object.properties)
    ]),

  // local weave_object_child(object) =
  //   "> a",

  // Weave functions for `array` type schemas
  local weave_array_type(object) =
    |||
      **Elements:**

      %(elements_type_docs)s
    ||| % {
      elements_type_docs: weave_type(object.items),
    },

  // Weave composite schemas
  local weave_one_of_type(object) =
    std.join(
      |||

        *or*

      |||,
      [|||

        `%(option_type)s`

      ||| % { option_type: get_type(type) } + weave_type(type) for type in object.oneOf]
    ),

  local weave_ref(object) =
    |||
      See %(ref)s
    ||| % { ref: object['$ref'] },

  // Util functions
  local get_type(object) =
    if std.objectHas(object, '$ref') then 'ref'
    else if std.objectHas(object, 'oneOf') then 'oneOf'
    else if std.objectHas(object, 'type') then object.type
    else 'any',
}