Skip to content

Commit

Permalink
Merge pull request #1512 from jplag/report-viewer/fix-highlight
Browse files Browse the repository at this point in the history
Fix code highlighting
  • Loading branch information
tsaglam authored Feb 2, 2024
2 parents 39ddae7 + 681e13a commit 3da1f57
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 78 deletions.
7 changes: 6 additions & 1 deletion docs/4.-Adding-New-Languages.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,4 +508,9 @@ In case you don't use the default layout for test source files, you can override
protected File getTestFileLocation() {
return super.getTestFileLocation();
}
```
```

# Adding code highlighting to the report-viewer
To ensure your language gets properly registered and its code is correctly highlighted in the report-viewer:
1) Add your language to the `ParserLanguage` enum in 'src/model/Language.ts'. As the value for the entry use its frontend name.
2) Add your language to the switch-case in `src/utils/CodeHighlighter.ts` and return the correct [highlight.js name](https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md). If your language is not supported by default, also register the language here.
4 changes: 2 additions & 2 deletions report-viewer/src/components/fileDisplaying/CodePanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import Interactable from '../InteractableComponent.vue'
import type { Match } from '@/model/Match'
import type { SubmissionFile } from '@/stores/state'
import { highlight } from '@/utils/CodeHighlighter'
import type { HighlightLanguage } from '@/model/Language'
import type { ParserLanguage } from '@/model/Language'
import { getMatchColor } from '@/utils/ColorUtils'

const props = defineProps({
Expand All @@ -80,7 +80,7 @@ const props = defineProps({
* Language of the file.
*/
highlightLanguage: {
type: String as PropType<HighlightLanguage>,
type: String as PropType<ParserLanguage>,
required: true
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ import ScrollableComponent from '../ScrollableComponent.vue'
import { VueDraggableNext } from 'vue-draggable-next'
import { ref, type PropType, type Ref } from 'vue'
import type { MatchInSingleFile } from '@/model/MatchInSingleFile'
import type { HighlightLanguage } from '@/model/Language'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faCompressAlt } from '@fortawesome/free-solid-svg-icons'
import { library } from '@fortawesome/fontawesome-svg-core'
import type { ParserLanguage } from '@/model/Language'

library.add(faCompressAlt)

Expand Down Expand Up @@ -75,7 +75,7 @@ const props = defineProps({
* Language of the files.
*/
highlightLanguage: {
type: String as PropType<HighlightLanguage>,
type: String as PropType<ParserLanguage>,
required: true
}
})
Expand Down
67 changes: 4 additions & 63 deletions report-viewer/src/model/Language.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ enum ParserLanguage {
SWIFT = 'Swift Parser',
TEXT = 'Text Parser (naive)',
SCXML = 'SCXML (Statechart XML)',
LLVM = 'LLVMIR Parser'
LLVM = 'LLVMIR Parser',
JAVASCRIPT = 'JavaScript',
TYPESCRIPT = 'Typescript Parser'
}

/**
Expand All @@ -37,65 +39,4 @@ function getLanguageParser(language: string): ParserLanguage {
throw new Error(`Language ${language} not found`)
}

/**
* Enum for the highlight.js languages
* The strings are the names of the languages in highlight.js (https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md)
*/
enum HighlightLanguage {
JAVA = 'java',
PYTHON = 'python',
CPP = 'cpp',
C_SHARP = 'csharp',
XML = 'xml',
GO = 'go',
KOTLIN = 'kotlin',
R_LANG = 'r',
RUST = 'rust',
SCALA = 'scala',
SCHEME = 'scheme',
SWIFT = 'swift',
TEXT = 'text'
}

/**
* Gets the highlight.js language for the given language
* @param language Language the files were parsed with
* @returns The language for highlight.js
*/
function getHighlightLanguage(language: ParserLanguage | undefined): HighlightLanguage {
switch (language) {
case ParserLanguage.PYTHON:
return HighlightLanguage.PYTHON
case ParserLanguage.CPP:
case ParserLanguage.CPP2:
return HighlightLanguage.CPP
case ParserLanguage.C_SHARP:
return HighlightLanguage.C_SHARP
case ParserLanguage.EMF_METAMODEL:
case ParserLanguage.EMF_METAMODEL_DYNAMIC:
case ParserLanguage.EMF_MODEL:
case ParserLanguage.SCXML:
return HighlightLanguage.XML
case ParserLanguage.GO:
return HighlightLanguage.GO
case ParserLanguage.KOTLIN:
return HighlightLanguage.KOTLIN
case ParserLanguage.R_LANG:
return HighlightLanguage.R_LANG
case ParserLanguage.RUST:
return HighlightLanguage.RUST
case ParserLanguage.SCALA:
return HighlightLanguage.SCALA
case ParserLanguage.SCHEME:
return HighlightLanguage.SCHEME
case ParserLanguage.SWIFT:
return HighlightLanguage.SWIFT
case ParserLanguage.TEXT:
return HighlightLanguage.TEXT
case ParserLanguage.JAVA:
default:
return HighlightLanguage.JAVA
}
}

export { ParserLanguage, getLanguageParser, HighlightLanguage, getHighlightLanguage }
export { ParserLanguage, getLanguageParser }
58 changes: 53 additions & 5 deletions report-viewer/src/utils/CodeHighlighter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { HighlightLanguage } from '@/model/Language'
import { ParserLanguage } from '@/model/Language'
import hljs from 'highlight.js'
import scheme from 'highlight.js/lib/languages/scheme'
import llvm from 'highlight.js/lib/languages/llvm'
import typescript from 'highlight.js/lib/languages/typescript'

/**
* Hightlights the given code with the given language.
Expand All @@ -10,10 +13,10 @@ import hljs from 'highlight.js'
* @param lang Language to highlight the code with
* @returns
*/
export function highlight(code: string, lang: HighlightLanguage) {
const highlightedCode = hljs.highlight(code, { language: lang.valueOf() }).value
export function highlight(code: string, lang: ParserLanguage) {
const highlightedCode = hljs.highlight(code, { language: getHighlightLanguage(lang) }).value
const openTags: string[] = []
const formatedCode = highlightedCode
const formattedCode = highlightedCode
.replace(/(<span [^>]*>)|(<\/span>)|(\n)/g, (match: string) => {
if (match === '\n') {
return '</span>'.repeat(openTags.length) + '\n' + openTags.join('')
Expand All @@ -28,5 +31,50 @@ export function highlight(code: string, lang: HighlightLanguage) {
return match
})
.split('\n')
return formatedCode
return formattedCode
}

function getHighlightLanguage(lang: ParserLanguage) {
switch (lang) {
case ParserLanguage.PYTHON:
return 'python'
case ParserLanguage.CPP:
case ParserLanguage.CPP2:
return 'cpp'
case ParserLanguage.C_SHARP:
return 'csharp'
case ParserLanguage.EMF_METAMODEL:
case ParserLanguage.EMF_METAMODEL_DYNAMIC:
case ParserLanguage.EMF_MODEL:
case ParserLanguage.SCXML:
return 'xml'
case ParserLanguage.GO:
return 'go'
case ParserLanguage.KOTLIN:
return 'kotlin'
case ParserLanguage.R_LANG:
return 'r'
case ParserLanguage.RUST:
return 'rust'
case ParserLanguage.SCALA:
return 'scala'
case ParserLanguage.SCHEME:
hljs.registerLanguage('scheme', scheme)
return 'scheme'
case ParserLanguage.SWIFT:
return 'swift'
case ParserLanguage.TEXT:
return 'plaintext'
case ParserLanguage.LLVM:
hljs.registerLanguage('llvm', llvm)
return 'llvm'
case ParserLanguage.JAVASCRIPT:
return 'javascript'
case ParserLanguage.TYPESCRIPT:
hljs.registerLanguage('typescript', typescript)
return 'typescript'
case ParserLanguage.JAVA:
default:
return 'java'
}
}
6 changes: 3 additions & 3 deletions report-viewer/src/viewWrapper/ComparisonViewWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import { type Ref, ref } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import ComparisonView from '@/views/ComparisonView.vue'
import { getHighlightLanguage, type HighlightLanguage } from '@/model/Language'
import type { Comparison } from '@/model/Comparison'
import { ComparisonFactory } from '@/model/factories/ComparisonFactory'
import LoadingCircle from '@/components/LoadingCircle.vue'
import { redirectOnError } from '@/router'
import type { ParserLanguage } from '@/model/Language'
const props = defineProps({
firstId: {
Expand All @@ -36,7 +36,7 @@ const props = defineProps({
})
const comparison: Ref<Comparison | null> = ref(null)
const language: Ref<HighlightLanguage | null> = ref(null)
const language: Ref<ParserLanguage | null> = ref(null)
// This eslint rule is disabled to allow the use of await in the setup function. Disabling this rule is safe, because the props are gathered from the url, so changing them would reload the pafe anyway.
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
Expand All @@ -50,7 +50,7 @@ ComparisonFactory.getComparison(props.firstId, props.secondId)
OverviewFactory.getOverview()
.then((overview) => {
language.value = getHighlightLanguage(overview.language)
language.value = overview.language
})
.catch((error) => {
redirectOnError(error, 'Could not load coparison:\n')
Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/views/ComparisonView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import MatchList from '@/components/fileDisplaying/MatchList.vue'
import FilesContainer from '@/components/fileDisplaying/FilesContainer.vue'
import { store } from '@/stores/store'
import Container from '@/components/ContainerComponent.vue'
import { HighlightLanguage } from '@/model/Language'
import { ParserLanguage } from '@/model/Language'
import hljsLightMode from 'highlight.js/styles/vs.css?raw'
import hljsDarkMode from 'highlight.js/styles/vs2015.css?raw'
import { MetricType } from '@/model/MetricType'
Expand All @@ -98,7 +98,7 @@ const props = defineProps({
required: true
},
language: {
type: Object as PropType<HighlightLanguage>,
type: Object as PropType<ParserLanguage>,
required: true
}
})
Expand Down

0 comments on commit 3da1f57

Please sign in to comment.