Compare commits
2 commits
fe6592bfa2
...
0e8b521f17
Author | SHA1 | Date | |
---|---|---|---|
|
0e8b521f17 | ||
|
058472d1b4 |
8 changed files with 246 additions and 24 deletions
|
@ -10,18 +10,17 @@
|
|||
|
||||
Um die Messungen etwas zu vereinfachen wurde ein Skript erstellt um die Aufrufe gesammelt durchzuführen. Um die
|
||||
Messungen durchzuführen werden die Befehl, wie in \ref{lst:calling_script_exec} dargestellt aufgerufen.
|
||||
Durch die nummerierten Präfixe können im Nachgang über die \textit{pgBadger}"=Berichte die SQL-Abfragen verglichen
|
||||
werden. Wichtig hierbei ist noch, dass vor dem ersten \textit{meascall}-Aufruf überprüft wird, ob die Docker-Container
|
||||
gestartet und initialisiert sind. Wenn dies nicht der Fall ist, laufen die Abfragen ins leere. Am einfachsten ist das
|
||||
über die Statistik von Docker zu ermitteln, ob die CPU-Auslastung auf einen niedrigen Level gefallen ist.
|
||||
Durch die nummerierten Präfixe können im Nachgang über die \textit{pgBadger}"=Berichte die \ac{SQL}"=Abfragen verglichen
|
||||
werden. Wichtig hierbei ist noch, dass vor dem \textit{measrun}-Aufruf überprüft wird, ob die Docker-Container
|
||||
gestartet und initialisiert sind. Wenn dies nicht der Fall ist, laufen die Abfragen ins leere. Am einfachsten ist das,
|
||||
wie dargestellt, über die Statistik von Docker zu ermitteln. Nun wird überwacht, das die CPU-Auslastung auf ein
|
||||
niedriges Level fällt, danach kann das Skript für die Messung gerufen werden.
|
||||
|
||||
\includecode[bash]{chapters/thesis/appendix04_calling_script.sh}{lst:calling_script}{Calling Script}
|
||||
|
||||
\begin{lstlisting}[language=Bash,caption={Aufrufe des Unterstützungsscriptes},label=lst:calling_script_exec]
|
||||
callscript.sh measinit
|
||||
callscript.sh -rppf=_testname measres
|
||||
callscript.sh -rppf=_testname meascall
|
||||
callscript.sh -rppf=_testname -rppn=2 meascall
|
||||
callscript.sh -rppf=_testname -rppn=3 meascall
|
||||
callscript.sh -rppf=_testname -rppn=4 meascall
|
||||
callscript.sh dcstats
|
||||
callscript.sh -rppf=_testname measrun
|
||||
\end{lstlisting}
|
|
@ -12,6 +12,7 @@ script_path="/opt/docker/timing.sh"
|
|||
pgbadger_out="/opt/docker/pgreport"
|
||||
report_postfix=""
|
||||
report_postno=""
|
||||
report_postmax="5"
|
||||
docker_name=dcpgbatch
|
||||
|
||||
COMPOSE_FILE=/opt/docker/docker-compose.yaml
|
||||
|
@ -20,14 +21,33 @@ gflog() {
|
|||
echo "follow the log: $domain_log"
|
||||
tail -f $domain_log
|
||||
}
|
||||
gflogrm() {
|
||||
echo "remove the log: $domain_log"
|
||||
rm "$domain_log"
|
||||
}
|
||||
gfconf() {
|
||||
nvim "$payara_config"
|
||||
}
|
||||
gfscript() {
|
||||
gflogcount=$(cat "$domain_log" | wc -l)
|
||||
outPath=$pgbadger_out$report_postfix/bash.out
|
||||
touch "$outPath"
|
||||
echo "" >>"$outPath"
|
||||
echo "============================================================" >>"$outPath"
|
||||
echo "calling number $report_postno / $report_postmax" >>"$outPath"
|
||||
echo "" >>"$outPath"
|
||||
bash $script_path | tee -a "$outPath"
|
||||
gflastlog=$(cat "$domain_log" | wc -l)
|
||||
gfcnt=$(($gflastlog - $gflogcount))
|
||||
printf "\n%-20s %+5s %+9s %+9s %+9s %+9s\n" "function" "Runs" "Min (ms)" "Avg (ms)" "Max (ms)" "1st (ms)" >>"$outPath"
|
||||
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-create \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-create-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-build \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-buildr-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-loadData \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-loaddt-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-loadDataMap \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-loaddm-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-renderData \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-rdrdat-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-renderLoad \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-rdrlst-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
tail -$gfcnt $domain_log | awk '/PerformanceCounter-render \/view/ { print $3 }' | awk 'BEGIN {min=500;max=0} {sum += $1; cnt += 1}; first == "" { first = $1 }; min > $1 { min = $1 } max < $1 { max = $1 } END { if (cnt < 1) {cnt = -1}; printf("%-20s %5i %9.3f %9.3f %9.3f %9.3f\n", "view-render-list", cnt, min, sum/cnt, max, first) }' >>"$outPath"
|
||||
}
|
||||
|
||||
pginit() {
|
||||
|
@ -68,9 +88,17 @@ pgrpres() {
|
|||
rm -R $pgbadger_out$report_postfix*
|
||||
fi
|
||||
}
|
||||
pgrpout() {
|
||||
echo "Show bash output"
|
||||
outPath=$pgbadger_out$report_postfix/bash.out
|
||||
cat "$outPath"
|
||||
}
|
||||
dccreate() {
|
||||
sudo docker compose -f $COMPOSE_FILE create --force-recreate
|
||||
}
|
||||
dcconf() {
|
||||
nvim $COMPOSE_FILE
|
||||
}
|
||||
dcstart() {
|
||||
sudo docker compose -f $COMPOSE_FILE start
|
||||
sleep 2
|
||||
|
@ -85,11 +113,24 @@ dcres() {
|
|||
dcstats() {
|
||||
sudo docker stats
|
||||
}
|
||||
meascall() {
|
||||
gfscript
|
||||
pgrp
|
||||
pglogrm
|
||||
}
|
||||
measrun() {
|
||||
for i in $(seq 1 $report_postmax); do
|
||||
report_postno=$i
|
||||
meascall
|
||||
done
|
||||
}
|
||||
for name in "$@"; do
|
||||
case $name in
|
||||
-rppf=*) report_postfix="${name#*=}" ;;
|
||||
-rppn=*) report_postno="${name#*=}" ;;
|
||||
-rppm=*) report_postmax="${name#*=}" ;;
|
||||
gflog) gflog ;;
|
||||
gflogrm) gflogrm ;;
|
||||
gfconf) gfconf ;;
|
||||
gfscript) gfscript ;;
|
||||
gfrestart) pgrpinit ;;
|
||||
|
@ -101,7 +142,9 @@ for name in "$@"; do
|
|||
pgrestart) pgrestart ;;
|
||||
pgrp) pgrp ;;
|
||||
pgrpres) pgrpres ;;
|
||||
pgrpout) pgrpout ;;
|
||||
dcinit) dccreate ;;
|
||||
dcconf) dcconf ;;
|
||||
dcstart) dcstart ;;
|
||||
dcstop) dcstop ;;
|
||||
dcres) dcres ;;
|
||||
|
@ -110,6 +153,7 @@ for name in "$@"; do
|
|||
pginit
|
||||
pgrpres
|
||||
pglogrm 0
|
||||
gflogrm
|
||||
dccreate
|
||||
dcstart
|
||||
;;
|
||||
|
@ -117,15 +161,13 @@ for name in "$@"; do
|
|||
dcstop
|
||||
pgrpres
|
||||
pglogrm 0
|
||||
gflogrm
|
||||
dcstart
|
||||
pgrp
|
||||
pglogrm
|
||||
;;
|
||||
meascall)
|
||||
gfscript
|
||||
pgrp
|
||||
pglogrm
|
||||
;;
|
||||
meascall) meascall ;;
|
||||
measrun) measrun ;;
|
||||
help)
|
||||
echo "CALLING: $0 <function> [ <function>]"
|
||||
echo "The overview of the functions of this script."
|
||||
|
@ -136,9 +178,11 @@ for name in "$@"; do
|
|||
echo "*** parameter ***"
|
||||
echo " -rppf=<val> Postfix name for the report-folder (used by gfscript, pgrp, pgrpres, measres, meascall)"
|
||||
echo " -rppn=<val> Postfix number for the report-folder (used by pgrp, measres, meascall)"
|
||||
echo " -rppm=<val> Count of calling meascall (used by measrun)"
|
||||
echo ""
|
||||
echo "*** glassfish ***"
|
||||
echo " gflog Show and follow the log of the glassfish server with $domain_name"
|
||||
echo " gflogrm Remove the log file of the glassfish server with $domain_name"
|
||||
echo " gfconf Open the configuration file from glassfish server"
|
||||
echo " gfscript Calls the testscript for the website"
|
||||
echo ""
|
||||
|
@ -150,19 +194,22 @@ for name in "$@"; do
|
|||
echo " pgconf Open the configuration file from postgresql"
|
||||
echo " pgrestart Restart the postgresql"
|
||||
echo " pgrp Generate the pgbadger report from postgresql log files"
|
||||
echo " pgrpout Show the saved output of the bash scripts"
|
||||
echo " pgrpres Resetet the output of pgbadger"
|
||||
echo ""
|
||||
echo "*** docker ***"
|
||||
echo " dcinit Docker erstellen"
|
||||
echo " dcstart Docker Container starten"
|
||||
echo " dcstop Docker Container stoppen"
|
||||
echo " dcres Docker Container stoppen und loeschen"
|
||||
echo " dcstats Docker live Statistik anzeigen"
|
||||
echo " dcinit Create the both docker container"
|
||||
echo " dcconf Open the configuration file for the docker container"
|
||||
echo " dcstart Start the both docker container"
|
||||
echo " dcstop Stop the both docker container stoppen"
|
||||
echo " dcres Stop and remote the both docker container"
|
||||
echo " dcstats Show the docker live statistik"
|
||||
echo ""
|
||||
echo "*** combine cmds ***"
|
||||
echo " measinit Initialize everthing after start"
|
||||
echo " measres reset data for new measuring"
|
||||
echo " meascall execute one measure"
|
||||
echo " measrun execute <rppm> calls of measure (default: 5 runs)"
|
||||
;;
|
||||
*)
|
||||
echo >&2 "Invalid option $name"
|
||||
|
|
|
@ -65,9 +65,9 @@ weitere Relationen notwendig sind.
|
|||
\includecode[SQL]{chapters/thesis/chapter03_documentlist.sql}{lst:documentlist}{Generische Abfrage der Dokumentenliste}
|
||||
\includecode[SQL]{chapters/thesis/chapter03_documentlist_sub.sql}{lst:documentlist_sub}{Sub-Abfrage pro Dokument}
|
||||
|
||||
Nach aktuellem Stand beinhaltet die Datenbank circa 5400 Briefe, für die jeweils 2-7 eingescannte Faksimile gespeichert
|
||||
werden. Diese Graphik-Dateien werden im TIFF-Format abgespeichert und benötigen zwischen 1 und 80 MB Speicherplatz.
|
||||
Dadurch kommt die Datenbank aktuell auf circa 3,8 GB.
|
||||
Nach aktuellem Stand beinhaltet die Datenbank circa 5400 Briefe, für die jeweils zwei bis sieben eingescannte Faksimile
|
||||
gespeichert werden. Diese Graphik-Dateien werden im TIFF-Format abgespeichert und benötigen zwischen 1 und 80 MB
|
||||
Speicherplatz. Dadurch kommt die Datenbank aktuell auf circa 3,8 GB.
|
||||
|
||||
Wie im Kapitel \ref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
|
||||
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher gehen wir nun weiter nach oben in den Schichten
|
||||
|
|
|
@ -260,6 +260,8 @@ abfragt.
|
|||
\section{Caching im \ac{JPA}}
|
||||
\label{sec:performance-investigation-application:caching-jpa}
|
||||
|
||||
%hier ein test vom acf: \acf{JPA}. aber ich seh ihn nicht
|
||||
|
||||
\mytodos{muss noch umgebaut werden, falsche Konfiguration erwischt}
|
||||
|
||||
%Die Cache-Einstellungen von \ac{JPA} werden über mehrere Einstellungen konfiguriert. Anhand von
|
||||
|
@ -562,6 +564,30 @@ FROM document d
|
|||
LEFT JOIN sitecity sc ON sc.id = d.city_id;
|
||||
\end{lstlisting}
|
||||
|
||||
Zusätzlich werden noch einige Indexe hinzugefügt, für eine bessere Performance bei der Abfrage, wie in
|
||||
\ref{lst:sql-materialized-view-index} zu sehen.
|
||||
|
||||
\begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view-index]
|
||||
CREATE INDEX idx_searchdocument_documentid
|
||||
ON searchdocument (documentid);
|
||||
|
||||
CREATE INDEX idx_searchdocument_author_surname_firstname
|
||||
ON searchdocument ((author->>'surname'), (author->>'firstname'));
|
||||
|
||||
CREATE INDEX idx_searchdocument_startdate
|
||||
ON searchdocument (startyear, startmonth, startday);
|
||||
|
||||
CREATE INDEX idx_searchdocument_addressees_first_entry
|
||||
ON searchdocument
|
||||
(((addressees->0->>'surname')::text), ((addressees->0->>'firstname')::text));
|
||||
|
||||
CREATE INDEX idx_searchdocument_city
|
||||
ON searchdocument (city);
|
||||
|
||||
CREATE INDEX idx_searchdocument_documentcategory
|
||||
ON searchdocument (documentcategory);
|
||||
\end{lstlisting}
|
||||
|
||||
% document, first/last, documentaddresseeperson, documentcoauthorperson, documentfacsimile und count
|
||||
% document, count, first/last
|
||||
\begin{table}[h!]
|
||||
|
@ -601,8 +627,6 @@ WHERE d.validuntil > NOW()
|
|||
AND d.ispublishedindb = true;
|
||||
\end{lstlisting}
|
||||
|
||||
\mytodos{Die Indizies noch mit aufnehmen!}
|
||||
|
||||
Nach dem Anpassungen haben sich dann die Werte aus \ref{tbl:measure-materialized-view-ext} ergeben.
|
||||
|
||||
\begin{table}[h!]
|
||||
|
@ -643,6 +667,84 @@ dieser Wert zu klein oder groß definiert ist, wird die Laufzeit verschlechtert.
|
|||
Laufzeit der Datenbankanfrage auf circa 20 ms verlängert. Wenn der Wert zu gering gewählt ist, dann wird zwar die
|
||||
Laufzeit der Datenbankanfrage minimal verkürzt, aber die \textit{map}"=Funktion wird dadurch verlängert.
|
||||
|
||||
Das aktivieren der Cache-Optionen wie in \ref{sec:performance-investigation-application:caching-openjpa} oder in
|
||||
\ref{sec:performance-investigation-application:caching-query} dargestellt, haben keine Auswirkung auf die Performance.
|
||||
Dies ist dadurch erklärbar, da keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der
|
||||
\textit{map}"=Funktion des eigenen Codes.
|
||||
|
||||
Nun wird noch geprüft, welche Performance das parsen der Json-Informationen im Server benötigt. Im ersten Schritt wird
|
||||
die Parse-Funktion auskommentiert und die Seite nochmal aufgerufen. Durch diese Umstellung fällt die Laufzeit der
|
||||
Datenermittlung auf circa 4 ms ab. Nun muss noch geprüft werden, welche Zeit nun der Client zum parsen der
|
||||
\ac{Json}"=Daten benötigt. Hierfür werden die Daten in einem versteckten \textbf{span}"=Element hinterlegt, wie es im
|
||||
Beispiel \ref{lst:jsf-datatable-json} zu sehen ist. Die hinterlegte \ac{CSS}"=Klasse ist zum auffinden der Elemente
|
||||
für den späteren Javascript. Das \textbf{ajax}"=Element im Beispiel ist notwendig, damit bei einem Seitenwechsel die neu
|
||||
übertragenen Elemente in eine lesbare Form gebracht werden.
|
||||
|
||||
\begin{lstlisting}[language=xml,caption={DataTable mit Json},label=lst:jsf-datatable-json]
|
||||
<p:ajax event="page" oncomplete="convertJsonData()"/>
|
||||
<p:column id="author" headerText="#{lang.List_Docs_Author}" sortable="true" sortBy="#{myObj.surname}">
|
||||
<h:outputText styleClass="json-convert" style="display: none;" value="#{myObj.authorJson}"/>
|
||||
</p:column>
|
||||
<p:column id="Addressee"
|
||||
headerText="#{lang.List_Docs_Addressee}"
|
||||
sortable="true"
|
||||
sortBy="#{(myObj.addresseePersonSet!=null and myObj.addresseePersonSet.size() > 0)?myObj.addresseePersonSet[0].addresseePerson:''}">
|
||||
<h:outputText styleClass="json-convert" style="display: none;" value="#{myObj.adresseeJson}" data="abc"/>
|
||||
</p:column>
|
||||
\end{lstlisting}
|
||||
|
||||
Um nun die übertragenen \ac{Json}"=Daten in eine darstellbare Form zu bringen, benötigt man noch eine
|
||||
JavaScript"=Funktion. Diese Funktion \ref{lst:jsf-datatable-json-convert} wird ermittelt erst alle versteckten Elemente,
|
||||
parsed den Inhalt und erstellt neue \ac{HTML}"=Elemente mit dem darzustellenden Inhalt. Zusätzlich wird noch eine
|
||||
Zeitmessung mit eingebaut, um die Laufzeit am Client für das Rendern in der Konsole anzuzeigen. Die Funktion wird nun
|
||||
direkt nach dem die Webseite fertig geladen wurde gerufen.
|
||||
|
||||
\begin{lstlisting}[language=javascript,caption={Wandeln von Json nach Html},label=lst:jsf-datatable-json-convert]
|
||||
function isEmpty(str) {
|
||||
return (str === null) || (str === undefined) || (typeof str === "string" && str.length === 0);
|
||||
}
|
||||
function convertJsonData() {
|
||||
let $jsonObj = $(".json-convert")
|
||||
, start = new Date()
|
||||
;
|
||||
|
||||
$.each($jsonObj, function() {
|
||||
let json = this.innerHTML
|
||||
, strEmpty = (json === null) || (typeof json === "string" && json.length === 0)
|
||||
, jsonDat = strEmpty ? null : JSON.parse(json)
|
||||
;
|
||||
if(!strEmpty) {
|
||||
let res = ""
|
||||
, $that = $(this)
|
||||
, $par = $that.parent()
|
||||
;
|
||||
$.each(jsonDat, function() {
|
||||
let hasOnlyOne = isEmpty(this.surname) || isEmpty(this.firstname)
|
||||
, pseudonymExists = !isEmpty(this.pseudonym)
|
||||
, namePart = "<span>" + (hasOnlyOne ? this.surname + this.firstname : this.surname + ", " + this.firstname) + "</span><br/>"
|
||||
, pseudoPart = pseudonymExists ? "<span class='w3-small w3-text-dark-gray'>" + this.pseudonym + "</span><br/>" : ""
|
||||
;
|
||||
res += namePart + pseudoPart;
|
||||
});
|
||||
$par.append(res);
|
||||
}
|
||||
});
|
||||
let end = new Date()
|
||||
, diff = (end - start)
|
||||
;
|
||||
console.log(Math.round(diff) + " ms");
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
convertJsonData();
|
||||
});
|
||||
\end{lstlisting}
|
||||
|
||||
Da nun am Client Code ausgeführt wird, nachdem die Daten übertragen wurden, kann nicht mehr alles über das Script
|
||||
durchgeführt werden. Daher werden nun die Laufzeiten am Server und am Client zusammenaddiert. Im Schnitt benötigt der
|
||||
Aufruf auf der Serverseite nun 70 ms und am Client sind es circa 13 ms. Dies bedeutet addiert kommt man mit dieser
|
||||
Lösung auf eine kürzere Laufzeit und weniger Last am Server.
|
||||
|
||||
%\mytodos{hier noch darauf eingehen, dass die Hauptarbeit nicht beim editieren sondern bei der Anzeige ist}
|
||||
\mytodos{Hier könnte man auch den Query-Cache nochmal verwenden, da die anfragen nun fix wären}
|
||||
\mytodos{Grundlagen zur Materialized-View noch hinterlegen}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
\chapter*{Abk\"{u}rzungsverzeichnis}
|
||||
|
||||
% Insert your acronyms here (Das Kürzel mit der längsten Bezeichnung sollte in den eckigen Klammern eingetragen werden)
|
||||
\begin{acronym}[API]
|
||||
\begin{acronym}[HTML]
|
||||
\acro{EJB}{Enterprise Java Beans}
|
||||
\acro{JSF}{Java Server Faces}
|
||||
\acro{ORM}{Object Relational Mapping}
|
||||
|
@ -30,6 +30,7 @@
|
|||
\acro{GB}{Gigabyte}
|
||||
\acro{SQL}{Structured Query Language}
|
||||
\acro{JVM}{Java Virtual Machine}
|
||||
\acro{JSON}{JavaScript Object Notation}
|
||||
\end{acronym}
|
||||
|
||||
\cleardoublepage
|
||||
|
|
BIN
thesis.pdf
BIN
thesis.pdf
Binary file not shown.
|
@ -36,6 +36,7 @@
|
|||
%lorem ipsum \lstinline|code| lorem ipsum
|
||||
|
||||
\input{tools/yaml_syntax_highlighting.tex}
|
||||
\input{tools/javascript_syntax_hightlighting.tex}
|
||||
|
||||
|
||||
%*************************************************************************
|
||||
|
|
72
tools/javascript_syntax_hightlighting.tex
Normal file
72
tools/javascript_syntax_hightlighting.tex
Normal file
|
@ -0,0 +1,72 @@
|
|||
\lstdefinelanguage[ECMAScript2015]{JavaScript}[]{JavaScript}{
|
||||
morekeywords=[1]{await, async, case, catch, class, const, default, do,
|
||||
enum, export, extends, finally, from, implements, import, instanceof,
|
||||
let, static, super, switch, throw, try},
|
||||
morestring=[b]` % Interpolation strings.
|
||||
}
|
||||
|
||||
\lstdefinelanguage{JavaScript}{
|
||||
morekeywords=[1]{break, continue, delete, else, for, function, if, in,
|
||||
new, return, this, typeof, var, void, while, with},
|
||||
% Literals, primitive types, and reference types.
|
||||
morekeywords=[2]{false, null, true, boolean, number, undefined,
|
||||
Array, Boolean, Date, Math, Number, String, Object},
|
||||
% Built-ins.
|
||||
morekeywords=[3]{eval, parseInt, parseFloat, escape, unescape},
|
||||
sensitive,
|
||||
morecomment=[s]{/*}{*/},
|
||||
morecomment=[l]//,
|
||||
morecomment=[s]{/**}{*/}, % JavaDoc style comments
|
||||
morestring=[b]',
|
||||
morestring=[b]"
|
||||
}[keywords, comments, strings]
|
||||
|
||||
\lstalias[]{ES6}[ECMAScript2015]{JavaScript}
|
||||
|
||||
\definecolor{mediumgray}{rgb}{0.3, 0.4, 0.4}
|
||||
\definecolor{mediumblue}{rgb}{0.0, 0.0, 0.8}
|
||||
\definecolor{forestgreen}{rgb}{0.13, 0.55, 0.13}
|
||||
\definecolor{darkviolet}{rgb}{0.58, 0.0, 0.83}
|
||||
\definecolor{royalblue}{rgb}{0.25, 0.41, 0.88}
|
||||
\definecolor{crimson}{rgb}{0.86, 0.8, 0.24}
|
||||
|
||||
\lstdefinestyle{JSES6Base}{
|
||||
backgroundcolor=\color{white},
|
||||
basicstyle=\ttfamily,
|
||||
breakatwhitespace=false,
|
||||
breaklines=false,
|
||||
captionpos=b,
|
||||
columns=fullflexible,
|
||||
commentstyle=\color{mediumgray}\upshape,
|
||||
emph={},
|
||||
emphstyle=\color{crimson},
|
||||
extendedchars=true, % requires inputenc
|
||||
fontadjust=true,
|
||||
frame=single,
|
||||
identifierstyle=\color{black},
|
||||
keepspaces=true,
|
||||
keywordstyle=\color{mediumblue},
|
||||
keywordstyle={[2]\color{darkviolet}},
|
||||
keywordstyle={[3]\color{royalblue}},
|
||||
numbers=left,
|
||||
numbersep=5pt,
|
||||
numberstyle=\tiny\color{black},
|
||||
rulecolor=\color{black},
|
||||
showlines=true,
|
||||
showspaces=false,
|
||||
showstringspaces=false,
|
||||
showtabs=false,
|
||||
stringstyle=\color{forestgreen},
|
||||
tabsize=2,
|
||||
title=\lstname,
|
||||
upquote=true % requires textcomp
|
||||
}
|
||||
|
||||
\lstdefinestyle{JavaScript}{
|
||||
language=JavaScript,
|
||||
style=JSES6Base
|
||||
}
|
||||
\lstdefinestyle{ES6}{
|
||||
language=ES6,
|
||||
style=JSES6Base
|
||||
}
|
Loading…
Reference in a new issue