Coder Social home page Coder Social logo

quill.delta's Introduction

ci.appveyor.com codecov.io

Quill Delta to HTML Converter

Converts Quill's Delta format to XML or HTML (insert ops only) with properly nested lists. This is a c# port of the javascript version by nozer.

Quickstart

Install with package manager:

Install-Package Quill.Delta

or with nuget:

nuget install Quill.Delta

Or with dotnet:

dotnet add package Quill.Delta

Quill.Delta can also be installed from nuget.org.

Usage

using Quill.Delta;
using Newtonsoft.Json.Linq;

var deltaOps = JArray.Parse(@"[
    {insert: ""Hello\n""},
    {insert: ""This is colorful"", attributes: {color: '#f00'}}
]");
var htmlConverter = new HtmlConverter(deltaOps);
string html = htmlConverter.Convert();

var xmlConverter = new XmlConverter(deltaOps);
XmlDocument xml = xmlConverter.Convert();

Configuration

HtmlConverter and XmlConverter take an configuration options object as the second (optional) argument. The HtmlConverterOptions and XmlConverterOptions objects share the following properties:

Option Default Description
ParagraphTag "p" Custom tag to wrap inline html elements
ClassPrefix "ql" A css class name to prefix class generating styles such as size, font, etc.
InlineStyles false If true, use inline styles instead of classes
MultiLineBlockquote true Instead of rendering multiple blockquote elements for quotes that are consecutive and have same styles(align, indent, and direction), it renders them into only one
MultiLineHeader true Same deal as multiLineBlockquote for headers
MultiLineCodeblock true Same deal as multiLineBlockquote for code-blocks
MultiLineParagraph true Set to false to generate a new paragraph tag after each enter press (new line)
LinkRel "" Specifies a value to put on the rel attr on links
LinkTarget "_blank" Specifies target for all links; use '' (empty string) to not generate target attribute. This can be overridden by an individual link op by specifiying the target with a value in the respective op's attributes.
AllowBackgroundClasses false If true, css classes will be added for background attr

HtmlConverter has the following extra properties:

Option Default Description
EncodeHtml true If true, <, >, /, ', ", & characters in content will be encoded.
CustomRenderer null A function that will be called to render custom (unknown) delta op to html (the default rendering code skips them)
BeforeRenderer null A function that will be called before rendering the current delta op. If it returns a value then this is used in place of the default rendering result.
AfterRenderer null A function that will be called after rendering the current delta op with the op and result. It should return the result (with optional modifications).

XmlConverter has the following extra properties:

Option Default Description
RootNodeTag "template" Specifies the root node of the resulting xml document
CustomRenderer null A function that will be called to render custom (unknown) delta op to xml
BeforeRenderer null A function that will be called before rendering the current delta op. If it returns a value then this is used in place of the default rendering result.
AfterRenderer null A function that will be called after rendering the current delta op with the op and result. It should return the result (with optional modifications).

Rendering Quill Formats

You can customize the rendering of Quill formats by registering to the render events before calling the Convert() method.

There are BeforeRender and AfterRender events and they are called multiple times before and after rendering each group. A group is one of:

  • continuous sets of inline elements
  • a video element
  • list elements
  • block elements (header, code-block, blockquote, align, indent, and direction)

BeforeRender event is called with raw operation objects for you to generate and return your own html. If you return an empty value, the system will return its own generated html.

AfterRender event is called with generated xml/html for you to inspect, maybe make some changes and return your modified or original html.

Following shows the parameter formats for beforeRender event:

groupType data
GroupType.Video {op: op object}
GroupType.Block {op: op object: ops: Array<op object>}
GroupType.List {items: Array<{item: block, innerList: list or null }> }
GroupType.InlineGroup {ops: Array<op object>}

op object will have the following format:

{
    insert: {
        type: '', // one of 'text' | 'image' | 'video' | 'formula',
        value: '' // some string value
    },
    attributes: {
        // ... quill delta attributes
    }
}

Rendering Inline Styles

If you are rendering to HTML that you intend to include in an email, using classes and a style sheet are not recommended, as not all browsers support style sheets. Quill.Delta supports rendering inline styles instead. The easiest way to enable this is to pass the option InlineStyles: new InlineStyles().

You can customize styles by setting the properties of the InlineStyles object:

var fontDic = new Dictionary<string, string>() {
    { "serif": "font-family: Georgia, Times New Roman, serif" },
    { "monospace": "font-family: Monaco, Courier New, monospace" }
}
var sizeDic = new Dictionary<string, string>() {
      { "small": "font-size: 0.75em" },
      { "large": "font-size: 1.5em" },
      { "huge": "font-size: 2.5em" }
};
new InlineStyles {
    Font = InlineStyles.MakeLookup(fontDic),
    Size = InlineStyles.MakeLookup(sizeDic),
    Indent = (value, op) =>
    {
        int indentSize = Int32.Parse(value) * 3;
        var side = op.Attributes != null &&
            op.Attributes.Direction == DirectionType.Rtl ? "right" : "left";
        return "padding-" + side + ":" + indentSize + "em";
    },
    Direction = (value, op) =>
    {
        if (value == "rtl")
        {
            var hasAlign = op.Attributes != null && op.Attributes.Align.HasValue;
            return $"direction:rtl{(hasAlign ? "" : "; text-align:inherit")}";
        }
        return null;
    }
};

Keys to this object are the names of attributes from Quill. The values are either a simple lookup table (like in the 'font' example above) used to map values to styles, or a fn(value, op) which returns a style string.

Rendering Custom Blot Formats

You need to tell system how to render your custom blot by suppliing the CustomRenderer handler in the XmlConverterOptions or HtmlConverterOptions.

If you would like your custom blot to be rendered as a block (not inside another block or grouped as part of inlines), then add renderAsBlock: true to its attributes.

Example:

using Newtonsoft.Json.Linq;
using Quill.Delta;

var ops = JArray.Parse(@"[
    {insert: {'my-blot': {id: 2, text: 'xyz'}}, attributes: {renderAsBlock: true|false}}
]");

var opts = new HtmlConverterOptions
{
    // customOp is your custom blot op
    // contextOp is the block op that wraps this op, if any.
    // If, for example, your custom blot is located inside a list item,
    // then contextOp would provide that op.
    CustomRenderer = (DeltaInsertOp op, DeltaInsertOp contextOp)
    {
        var insert = (InsertDataCustom)op.Insert;
        if (insert.CustomType == "my-blot")
        {
            var val = (JObject)insert.Value;
            return $"<span id=\"{val["id"]}\">{val["text"]}</span>";
        }
        else
        {
            return "Unmanaged custom blot!";
        }
    }
};
var converter = new HtmlConverter(ops, opts);
string html = converter.Convert();

customOp object will have the following format:

{
    insert: {
        type: string // whatever you specified as key for insert, in above example: 'my-blot'
        value: any // value for the custom blot
    },
    attributes: {
        // ... any attributes custom blot may have
    }
}

Advanced Custom Rendering Using Grouped Ops

If you want to do the full rendering yourself, you can do so by getting the processed & grouped ops.

var groupedOps = converter.GetGroupedOps();

Each element in groupedOps array will be an instance of the following types:

type properties
InlineGroup Ops: IList<DeltaInsertOp>
VideoItem Op: DeltaInsertOp
BlockGroup Op: DeltaInsertOp, Ops: IList<DeltaInsertOp>
ListGroup Items: IList<ListItem>
ListItem: { Item: BlockGroup, InnerList: ListGroup }
BlotBlock Op: DeltaInsertOp

BlotBlock represents custom blots with renderAsBlock:true property pair in its attributes

See above for DeltaInsertOp properties.

Local Development

Hacking on Quill.Delta is easy! To quickly get started clone the repo:

$ git clone https://github.com/blushingpenguin/Quill.Delta.git
$ cd Quill.Delta

To compile the code and run the tests just open the solution in Visual Studio 2017 Community Edition. To generate a code coverage report run cover.bat from the solution directory.

quill.delta's People

Contributors

blushingpenguin avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.