PINE LIBRARY

CSVParser

█ OVERVIEW

The library contains functions for parsing and importing complex CSV configurations (with a special simple syntax) into a special hierarchical object (of type objProps) as follows:
snapshot

Functions:
  • parseConfig() - reads CSV text into an objProps object.
  • toT() - displays the contents of an objProps object in a table form, which allows to check the CSV text for syntax errors.
  • getPropAr() - returns objProps.arS array for child object with `prop` key in mpObj map (or na if not found)


This library is handy in allowing users to store presets for the scripts and switch between them (see, e.g., my HTF moving averages script where users can switch between several preset configuations of 24 MA's across 5 timeframes).

█ HOW THE SCRIPT WORKS.
The script works as follows:
  • all values read from config text are stored as strings

  • Nested brackets in config text create a named nested objects of objProps0, ... , objProps9 types.

  • objProps objects of each level have the following fields:

    - array<string> arS for storing values without names (e.g. "12, 23" will be imported into a string array arS as ["12","23"])

    - map<string, string> mpS for storing items with names (e.g. "tf = 60, length = 21" will be imported as <"tf", "60"> and <"length", "21"> pairs into mpS )

    - map<string, objPropsN> mpObj for storing nested objects (e.g. "TF1(tf=60, length(21,50,100))" creates a <"TF1, objProps0 object> pair in mpObj map property of the top level object (objProps) , "tf=60" is stored as <"tf", "60"> key-value pair in mpS map property of a next level object (objProps0) and "length (...)" creates a <"length", objProps1> pair in objProps0.mpObj map while length values are stored in objProps1.arS array as strings. Every opening bracket creates a next level objProps object.

  • If objects or properties with duplicate names are encountered only the latest is imported
    (e.g. for "TF1(length(12,22)), TF1(tf=240)" only "TF1(tf=240)" will be imported

  • Line breaks are not regarded as part of syntax (i.e. values are imported with line breaks, you can supply

  • symbols "(", ")", "," and "=" are special characters and cannot be used within property values (with the exception of a quoted text as a value of a property as explained below)

  • named properties can have quoted text as their value. In that case special characters within quotation marks are regarded as normal characters. Text between "=" and opening quotation mark as well as text following the closing quotation mark and until next property value is ignored. E.g. "quote = ignored "The quote" also ignored" will be imported as <"quote", "The quote">. Quotation marks within quotes must be excaped with "\".

  • if a key names happens to be a multi-line then only first line containing non-space characters (trimmed from spaces) is taken as a key.

  • ")," or ") ," and similar do not create an empty ("") array item while ",," does. (",)" creates an "" array item)


█  CSV CONFIGURATION SYNTAX

Unnamed values: just list them comma separated and they will be imported into arS of the object of the current level.

Named values: use "=" sign as follows: "property1=value1, property2 = value2"

Value of several objects: Use brackets after the name of the object ant list all object properties within the brackets (including its child objects if necessary). E.g. "TF1(tf =60, length(21,200), TF2(tf=240, length(50,200)"

Named and unnamed values as well as objects can go in any order. E.g. "12, tf=60, 21" will be imported as follows: "12", "21" will go to arS array and <"tf", "60"> will go to mpS maP of objProps (the top level object).

You can play around and test your config text using demo in this library, just edit your text in script settings and see how it is parsed into objProps objects.

█  USAGE RECOMMENDATIONS AND SAMPLE USE
I suggest the following approach:
- create functions for your UDT which can set properties by name.
- create enumerator functions which iterates through all the property names (supplied as a const string array) and imports their values into the object


█  SAMPLE USE
A sample use of this library can be seen in my Multi-timeframe 24 moving averages + BB+SAR+Supertrend+VWAP script where settings for the MAs across many timeframes are imported from CSV configurations (presets).

█ FULL LIST OF FUNCTIONS AND PROPERTIES

nzs(_s, nz)
  Like nz() but for strings. Returns `nz` arg (default = "") if _s is na.
  Parameters:
    _s (string)
    nz (string)

method init(this)
  Initializes objProps obj (creates child maps and arrays)
  Namespace types: objProps
  Parameters:
    this (objProps)

method toT(this, nz)
  Outputs objProps to string matrices for further display using autotable().
  Namespace types: objProps, objProps1, ..., objProps9
  Parameters:
    this (objProps/objProps1/..../objProps9)
    nz (string)
  Returns: A tuple [mxS, mxMerge, mxBgClr] - value, merge and color matrix (autotable() parameters)

method parseConfig(this, s)
  Reads config text into objProps (unnamed values into arS, named into mpS, sub-levels into mpObj)
  Namespace types: objProps
  Parameters:
    this (objProps)
    s (string)

method getPropArS(this, prop)
  Returns a string array of values for a given property name `prop`. Looks for a key `prop` in objProps.mpObj
if finds <prop, obj> pair returns obj.arS, otherwise returns na. Returns a reference to the original, not a copy.
  Namespace types: objProps, objProps1, ..., objProps8
  Parameters:
    this (objProps/objProps1/..../objProps8)
    prop (string)

method getPropVal(this, prop, id)
  Checks if there is an array of values for property `prop` and returns its `id`'s element or na if not found
  Namespace types: objProps, objProps1, ..., objProps8
  Parameters:
    this (objProps/objProps1/..../objProps8): objProps object containing array of property values in a child objProp object corresponding to propertty name.
    prop (string): (string) Name of the property
    id (int): (int) Id of the element to be returned from the array pf property values

objProps9 type
  Object for storing values read from CSV relating to a particular object or property name.
  Fields:
    mpS (map<string, string>): (map(<string, string>) Stores property values as <key, value> pairs
    arS (array<string>): (string[]) Array of values

objProps, objProps0, ... objProps8 types
  Object for storing values read from CSV relating to a particular object or property name.
  Fields:
    mpS (map<string, string>): (map(<string, string>) Stores property values as <key, value> pairs
    arS (array<string>): (string[]) Array of values
    mpObj (map<string, objProps1>): (map(<string, objProps... >) Stores objProps objects containing properties's data as <property name, objProp...> pairs
CSVinputsstringstrings

Pine library

In true TradingView spirit, the author has published this Pine code as an open-source library so that other Pine programmers from our community can reuse it. Cheers to the author! You may use this library privately or in other open-source publications, but reuse of this code in a publication is governed by House rules.

Disclaimer