1

I am trying to design a schema for pairing styling data with text. However, I need it to pair styling metadata to only one part of a larger string.

For example:

"This is a test string"

I want to style This as italic, and test as bold.

The question is, how do I efficiently designate subsections of this string as being styled?

I've considered the following methods, but they feel clunky and wasteful.

Inline

[Italic]This[/Italic] is a [Bold]Test[/Bold] string"

Pros:

  • Inlining the styling queues saves on needing to create a large number of secondary fields containing metadata.
  • Reduces size of JSON messages

Cons:

  • Requires the rendering client to spend time decoding the styling fields. String manipulation is tedious and relatively resource intensive.

Segmented String Fields

This method involves splitting each stylized segmented of the larger string into distinct JSON objects, each of which has two fields:

value, a string that contains the full text of the segment style, an array of strings that contains the full style description of the value string.

The resultant JSON object following this schema is:

{
  "content": [
    
  {
    "value" : "This",
    "style" : ["Italic"]
  },
  {
    "value" : " is a ",
    "style" : []
  },
  {
    "value": "test",
    "style": ["Bold"]
  },
  {
    "value" : " string.",
    "style" : []
  }
  ]
}

Pros:

  • Readable
  • Easy for the client to parse
  • Flexible

Cons:

  • Space-inefficient

The Problem

I'm stumped. Are there pros and cons of my existing solutions that I missed? Are there entirely different solutions you would recommend? Please weigh in.

3
  • (Is there any advantage of the second one compared to the first one?)
    – user253751
    Jan 27, 2023 at 22:28
  • I would go with inline strings, but why reinvent the wheel? Use an HTML subset, it may allow you to use existing libs or tools. which can make parsing and processing a lot easier.
    – Doc Brown
    Jan 27, 2023 at 22:52
  • @J_H no, markdown is terrible and ambiguous, and I wish people would stop recommending it for machine-to-machine communication.
    – user253751
    Jan 27, 2023 at 23:44

1 Answer 1

3

There are many reasonable approaches I have seen.

Markup languages are often quite reasonable, and often not that hard to parse. Typical choices include

  • Markdown (CommonMark)
  • BBCode
  • safe HTML subsets or XML

However, when handled improperly, there can be security issues such as XSS.

Providing a data structure that represents the already-parsed syntax tree can be very convenient for clients, and the space overhead is often not that dramatic. There are lots of different data representations you could choose. You have demonstrated tagging every text item, but plain strings can be left bare. For example, a similar encoding could be:

{ {"Italic": "This"}
, " is a "
, {"Bold": "test"}
, " string."
}

One can also use arrays, similar to how XML-like structures are often represented, and also known as sexprs:

[ ["Italic", "This"]
, " is a "
, ["Bold", "test"]
, " string."
]

A different way of encoding markup is to have a plain string, and then describe string slices that should be highlighted. For example:

{
  "text": "This is a test string.",
  "styles": [
    [0, 4, "Italic"],
    [10, 14, "Bold"]
  ]
}

However, this representation supports overlapping styles, which is likely invalid.

Which representation you should choose will depend mainly on how the clients will be using this data, and whether the clients can trust the data source. If the markup is trustworthy, then just sending HTML fragments around can be entirely reasonable. If the highlighted text shall be rendered via custom widgets or in a platform-independent way, a pre-parsed syntax tree might be simpler. The overhead of shipping such data structures is typically negligible, at least in a web context. Tracking style spans separately allows easy processing of plaintext contents, but probably doesn't have significant advantages otherwise.

If you're now even more confused than before, then just stick to your second solution – representing the markup structure with JSON objects. This representation is easy to work with in a variety of use cases. The other representations make it easier to make errors (which might be security-relevant). First make it work, then make it fast. If truly necessary, you can later figure out ways to make this more performant (though you shouldn't use compression if the data contains untrusted parts).

1
  • 2
    Bold+italic is completely valid. But you might want it as a separate style.
    – gnasher729
    Jan 28, 2023 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.