Welcome to mirror list, hosted at ThFree Co, Russian Federation.

highlight_utils.js « workers « source_viewer « components « vue_shared « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 057a1c2d1133b305393354da499fa3e37f007d3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import hljs from 'highlight.js/lib/core';
import languageLoader from '~/content_editor/services/highlight_js_language_loader';
import { registerPlugins } from '../plugins/index';
import { LINES_PER_CHUNK, NEWLINE, ROUGE_TO_HLJS_LANGUAGE_MAP } from '../constants';

const loadLanguage = async (language) => {
  const languageDefinition = await languageLoader[language]();
  hljs.registerLanguage(language, languageDefinition.default);
};

const loadSubLanguages = async (languageDefinition) => {
  // Some files can contain sub-languages (i.e., Svelte); this ensures that sub-languages are also loaded
  if (!languageDefinition?.contains) return;

  // generate list of languages to load
  const languages = new Set(
    languageDefinition.contains
      .filter((component) => Boolean(component.subLanguage))
      .map((component) => component.subLanguage),
  );

  if (languageDefinition.subLanguage) {
    languages.add(languageDefinition.subLanguage);
  }

  await Promise.all([...languages].map(loadLanguage));
};

const initHighlightJs = async (fileType, content, language) => {
  registerPlugins(hljs, fileType, content, true);
  await loadLanguage(language);
  await loadSubLanguages(hljs.getLanguage(language));
};

const splitByLineBreaks = (content = '') => content.split(/\r?\n/);

const createChunk = (language, rawChunkLines, highlightedChunkLines = [], startingFrom = 0) => ({
  highlightedContent: highlightedChunkLines.join(NEWLINE),
  rawContent: rawChunkLines.join(NEWLINE),
  totalLines: rawChunkLines.length,
  startingFrom,
  language,
});

const splitIntoChunks = (language, rawContent, highlightedContent) => {
  const result = [];
  const splitRawContent = splitByLineBreaks(rawContent);
  const splitHighlightedContent = splitByLineBreaks(highlightedContent);

  for (let i = 0; i < splitRawContent.length; i += LINES_PER_CHUNK) {
    const chunkIndex = Math.floor(i / LINES_PER_CHUNK);
    const highlightedChunk = splitHighlightedContent.slice(i, i + LINES_PER_CHUNK);
    const rawChunk = splitRawContent.slice(i, i + LINES_PER_CHUNK);
    result[chunkIndex] = createChunk(language, rawChunk, highlightedChunk, i);
  }

  return result;
};

const highlight = async (fileType, rawContent, lang) => {
  const language = ROUGE_TO_HLJS_LANGUAGE_MAP[lang.toLowerCase()];
  let result;

  if (language) {
    await initHighlightJs(fileType, rawContent, language);
    const highlightedContent = hljs.highlight(rawContent, { language }).value;
    result = splitIntoChunks(language, rawContent, highlightedContent);
  }

  return result;
};

export { highlight, splitIntoChunks };