slate#Block TypeScript Examples

The following examples show how to use slate#Block. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
 * A Slate plugin to highlight code syntax.
 */
export function SlatePrism(optsParam: OptionsFormat = {}): Plugin {
  const opts: Options = new Options(optsParam);

  return {
    decorateNode: (node, editor, next) => {
      if (!opts.onlyIn(node)) {
        return next();
      }
      return decorateNode(opts, Block.create(node as Block));
    },

    renderDecoration: (props, editor, next) =>
      opts.renderDecoration(
        {
          children: props.children,
          decoration: props.decoration,
        },
        editor as any,
        next
      ),
  };
}
Example #2
Source File: slate.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
makeFragment = (text: string, syntax?: string): Document => {
  const lines = text.split('\n').map(line =>
    Block.create({
      type: 'code_line',
      nodes: [Text.create(line)],
    })
  );

  const block = Block.create({
    data: {
      syntax,
    },
    type: 'code_block',
    nodes: lines,
  });

  return Document.create({
    nodes: [block],
  });
}
Example #3
Source File: query_field.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
makeFragment = (text: string) => {
  const lines = text.split('\n').map((line: any) =>
    Block.create({
      type: 'paragraph',
      nodes: [Text.create(line)],
    } as any)
  );

  const fragment = Document.create({
    nodes: lines,
  });
  return fragment;
}
Example #4
Source File: index.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the decoration for a node
 */
function decorateNode(opts: Options, block: Block) {
  const grammarName = opts.getSyntax(block);
  const grammar = Prism.languages[grammarName];
  if (!grammar) {
    // Grammar not loaded
    return [];
  }

  // Tokenize the whole block text
  const texts = block.getTexts();
  const blockText = texts.map(text => text && text.getText()).join('\n');
  const tokens = Prism.tokenize(blockText, grammar);

  // The list of decorations to return
  const decorations: Decoration[] = [];
  let textStart = 0;
  let textEnd = 0;

  texts.forEach(text => {
    textEnd = textStart + text!.getText().length;

    let offset = 0;
    function processToken(token: string | Prism.Token, accu?: string | number) {
      if (typeof token === 'string') {
        if (accu) {
          const decoration = createDecoration({
            text: text!,
            textStart,
            textEnd,
            start: offset,
            end: offset + token.length,
            className: `prism-token token ${accu}`,
            block,
          });
          if (decoration) {
            decorations.push(decoration);
          }
        }
        offset += token.length;
      } else {
        accu = `${accu} ${token.type} ${token.alias || ''}`;

        if (typeof token.content === 'string') {
          const decoration = createDecoration({
            text: text!,
            textStart,
            textEnd,
            start: offset,
            end: offset + token.content.length,
            className: `prism-token token ${accu}`,
            block,
          });
          if (decoration) {
            decorations.push(decoration);
          }

          offset += token.content.length;
        } else {
          // When using token.content instead of token.matchedStr, token can be deep
          for (let i = 0; i < token.content.length; i += 1) {
            // @ts-ignore
            processToken(token.content[i], accu);
          }
        }
      }
    }

    tokens.forEach(processToken);
    textStart = textEnd + 1; // account for added `\n`
  });

  return decorations;
}
Example #5
Source File: index.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
/**
 * Return a decoration range for the given text.
 */
function createDecoration({
  text,
  textStart,
  textEnd,
  start,
  end,
  className,
  block,
}: {
  text: Text; // The text being decorated
  textStart: number; // Its start position in the whole text
  textEnd: number; // Its end position in the whole text
  start: number; // The position in the whole text where the token starts
  end: number; // The position in the whole text where the token ends
  className: string; // The prism token classname
  block: Block;
}): Decoration | null {
  if (start >= textEnd || end <= textStart) {
    // Ignore, the token is not in the text
    return null;
  }

  // Shrink to this text boundaries
  start = Math.max(start, textStart);
  end = Math.min(end, textEnd);

  // Now shift offsets to be relative to this text
  start -= textStart;
  end -= textStart;

  const myDec = block.createDecoration({
    object: 'decoration',
    anchor: {
      key: text.key,
      offset: start,
      object: 'point',
    },
    focus: {
      key: text.key,
      offset: end,
      object: 'point',
    },
    type: TOKEN_MARK,
    data: { className },
  });

  return myDec;
}