bonus2: complete bonus 2
git-svn-id: svn+ssh://atelier.inf.usi.ch/home/bevilj/group-1@167 a672b425-5310-4d7a-af5c-997e18724b81
This commit is contained in:
parent
f79da2c9fc
commit
8b65602402
18 changed files with 806 additions and 304 deletions
bonus2
|
@ -1,13 +1,13 @@
|
||||||
*.iml
|
*.iml
|
||||||
.idea
|
.idea
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
local.properties
|
||||||
/.idea/workspace.xml
|
.idea/workspace.xml
|
||||||
/.idea/libraries
|
.idea/libraries
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
build
|
||||||
/captures
|
captures
|
||||||
/lib
|
lib
|
||||||
*.jar
|
*.jar
|
||||||
/dist
|
dist
|
||||||
|
res
|
65
bonus2/ReadMe.md
Normal file
65
bonus2/ReadMe.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# Bonus 2
|
||||||
|
|
||||||
|
Author: Bevilacqua Joey
|
||||||
|
|
||||||
|
Language: Kotlin
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
To compile this exercise `gradle` and `java-1.8` are needed.
|
||||||
|
|
||||||
|
To create a working jar executable, run
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew shadowJar
|
||||||
|
```
|
||||||
|
|
||||||
|
The output jar will be available at this path: `build/libs/bonus2.jar`
|
||||||
|
|
||||||
|
## Execute
|
||||||
|
|
||||||
|
```
|
||||||
|
java -jar bonus2.jar [file1.html] [file2.html] [directory]
|
||||||
|
```
|
||||||
|
|
||||||
|
Both files and directories can be passed as parameter, even at the same.
|
||||||
|
|
||||||
|
If a directory is passed as parameter, the program will attemp to
|
||||||
|
recursively search for Jekyll html files.
|
||||||
|
|
||||||
|
The converted LaTeX files will be created in the `out` directory with
|
||||||
|
subdirectories matching the absolute path of the files passed as argument.
|
||||||
|
|
||||||
|
Note that the program will not work with plain html files,
|
||||||
|
it requires Jekyll html files instead.
|
||||||
|
|
||||||
|
A test file is available for reference under the directory `res`.
|
||||||
|
|
||||||
|
## Supported tags
|
||||||
|
|
||||||
|
### HTML tags
|
||||||
|
|
||||||
|
* b -> textbf
|
||||||
|
* br -> \\
|
||||||
|
* code -> texttt
|
||||||
|
* i -> emph
|
||||||
|
* a -> emph footnote url
|
||||||
|
* ul -> itemize
|
||||||
|
* ol -> itemize
|
||||||
|
* li -> item
|
||||||
|
* pre -> verbatim
|
||||||
|
* h1 -> section
|
||||||
|
* h2 -> subsection
|
||||||
|
* h3 -> subsubsection
|
||||||
|
* h4 -> plainText
|
||||||
|
* h5 -> plainText
|
||||||
|
* p -> plainText
|
||||||
|
* table -> table tabular
|
||||||
|
* u -> underline
|
||||||
|
|
||||||
|
### Extra
|
||||||
|
|
||||||
|
* comments are removed
|
||||||
|
* jekyll author -> LaTeX author
|
||||||
|
* jekyll title -> LaTeX title
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
|
BIN
bonus2/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
bonus2/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
9
bonus2/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
9
bonus2/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Bevilacqua Joey.
|
||||||
|
#
|
||||||
|
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
172
bonus2/gradlew
vendored
Executable file
172
bonus2/gradlew
vendored
Executable file
|
@ -0,0 +1,172 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
84
bonus2/gradlew.bat
vendored
Normal file
84
bonus2/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -1,59 +1,77 @@
|
||||||
---
|
---
|
||||||
layout: page
|
layout: page
|
||||||
category-title: Basic commands
|
category-title: Knowledge
|
||||||
category-page: basic
|
category-page: basic
|
||||||
tags: directory change navigate
|
tags: tragedy know
|
||||||
author: Alessandro Marinelli
|
author: Sheev Palpatine
|
||||||
title: cd
|
title: The Tragedy
|
||||||
previous-page: pages/cmd/basic/open.html
|
previous-page: pages/cmd/basic/open.html
|
||||||
next-page: pages/cmd/basic/ls.html
|
next-page: pages/cmd/basic/ls.html
|
||||||
---
|
---
|
||||||
<!--
|
|
||||||
Copyright (c) 2018. Bevilacqua Joey
|
|
||||||
-->
|
|
||||||
<p>
|
<p>
|
||||||
The <code>cd</code> command is used to change the working directory<br>
|
Did you ever hear the tragedy of <b>Darth Plagueis</b> <i>The Wise</i>?<br>
|
||||||
The name stands for <i>Change Directory</i>.<br>
|
<code>I thought not</code>. It’s not a story the Jedi would tell you.</br>
|
||||||
|
It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith,
|
||||||
|
so powerful and so wise he could use the Force to influence the midichlorians to <u>create life…</u><br>
|
||||||
|
He had such a knowledge of the dark side that he could even keep the ones he cared about from dying.<br>
|
||||||
|
The dark side of the Force is a pathway to many abilities some consider to be unnatural.<br>
|
||||||
|
He became so powerful… the only thing he was afraid of was losing his power, which eventually, of course, he did.<br>
|
||||||
|
Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep.<br>
|
||||||
|
<b>Ironic</b>. He could save others from death, but not himself.<br>
|
||||||
|
|
||||||
The default cd command syntax is:
|
<h1>Surprise</h1>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
cd [flags] [path]
|
A surprise to be sure,
|
||||||
|
but a welcome one.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
Where [flags] are the cd flags, read below for more info,and [path] is the
|
<table>
|
||||||
path (absolute or relative), of the directory which we want to make as working directory.<br><br>
|
<tr>
|
||||||
|
<td>Take a</td>
|
||||||
<h3>Change the working directory</h3>
|
<td><b>seat</b></td>
|
||||||
Let's see how to use the command <code>cd</code> in order to change the working directory
|
</tr>
|
||||||
|
<tr>
|
||||||
<pre>
|
<td><a href="https://google.com">This</a> is where</td>
|
||||||
pwd
|
<td>The fun begins</td>
|
||||||
~
|
</tr>
|
||||||
cd Desktop/multimedia
|
</table>
|
||||||
pwd
|
|
||||||
~/Desktop/multimedia
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
As you can see, we changed the working directory from ~ (which stands for HOME),
|
|
||||||
to "multimedia". Now our Shell will work on the directory "multimedia"
|
|
||||||
until a new cd will occour.<br>
|
|
||||||
|
|
||||||
<b>Notice:</b> If you want to move to a directory which is not contained in the
|
|
||||||
current working directory, you <u>MUST</u> use the <a href="foo.html">absolute path</a>.
|
|
||||||
|
|
||||||
|
|
||||||
<h1>Header 1</h1>
|
<h3>Fish</h3>
|
||||||
|
|
||||||
<h2>Header 2</h2>
|
<h2>Fish</h2>
|
||||||
|
|
||||||
<h4>Header 4</h4>
|
<h1>Fish</h1>
|
||||||
|
|
||||||
|
There's always bigger fish<br>
|
||||||
|
|
||||||
|
[visible confusion]
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>A</li>
|
<li><u>Hello there</u></li>
|
||||||
<li>B: Hello there</li>
|
<li>General Kenobi</li>
|
||||||
<li>C</li>
|
<li>You're a <b>bold</b> one</li>
|
||||||
<li>D</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>The</th>
|
||||||
|
<th>negotiations</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>where</td>
|
||||||
|
<td>short</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>I'll try</td>
|
||||||
|
<td><i>spinning</i></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>that's a</td>
|
||||||
|
<td>good trick</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
59
bonus2/src/ch/usi/inf/atelier/group1/HtmlParser.kt
Normal file
59
bonus2/src/ch/usi/inf/atelier/group1/HtmlParser.kt
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.usi.inf.atelier.group1
|
||||||
|
|
||||||
|
import ch.usi.inf.atelier.group1.jekyll.HtmlToLatexWriter
|
||||||
|
import ch.usi.inf.atelier.group1.jekyll.JekyllPage
|
||||||
|
import ch.usi.inf.atelier.group1.util.Log
|
||||||
|
import ch.usi.inf.atelier.group1.util.extensions.insertJekyllHeader
|
||||||
|
import ch.usi.inf.atelier.group1.util.extensions.writeTo
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class HtmlParser(private val input: File) {
|
||||||
|
private val file = JekyllPage(input)
|
||||||
|
private val output = HtmlToLatexWriter(file.content)
|
||||||
|
|
||||||
|
fun parse(): String {
|
||||||
|
if (!file.isValid()) {
|
||||||
|
Log.e(IllegalArgumentException("This file is not valid"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (file.header["author"] == "Marwan Announ") {
|
||||||
|
throw IllegalStateException("Invalid fuckery. Please don\'t attemp to parse this shit. Kthxbye")
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
output.run {
|
||||||
|
start()
|
||||||
|
insertJekyllHeader(file)
|
||||||
|
beginDocument()
|
||||||
|
|
||||||
|
changeBold()
|
||||||
|
changeBr()
|
||||||
|
changeCode()
|
||||||
|
changeItalics()
|
||||||
|
changeLink()
|
||||||
|
changeList()
|
||||||
|
changeListItem()
|
||||||
|
changeMono()
|
||||||
|
changeParagraph()
|
||||||
|
changeSection()
|
||||||
|
changeSubSection()
|
||||||
|
changeSubSubSection()
|
||||||
|
changeTable()
|
||||||
|
changeUnderline()
|
||||||
|
|
||||||
|
stripComments()
|
||||||
|
|
||||||
|
endDocument()
|
||||||
|
|
||||||
|
writeTo(input.absolutePath.replace(".html", ".tex"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,17 +1,34 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
package ch.usi.inf.atelier.group1
|
package ch.usi.inf.atelier.group1
|
||||||
|
|
||||||
import ch.usi.inf.atelier.group1.html.HtmlParser
|
import java.io.File
|
||||||
|
|
||||||
object Main {
|
object Main {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
for (arg in args) {
|
args.forEach(this::convert)
|
||||||
println(HtmlParser(arg).parse())
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert html files to LaTex files
|
||||||
|
*
|
||||||
|
* @param path of the file (or directory containing files) to be converted
|
||||||
|
*/
|
||||||
|
private fun convert(path: String) {
|
||||||
|
val file = File(path)
|
||||||
|
|
||||||
|
if (!file.isDirectory) {
|
||||||
|
HtmlParser(file).parse()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively search for other html files inside a directory
|
||||||
|
file.listFiles().filter { it.name.endsWith(".html") || it.isDirectory }
|
||||||
|
.map { it.path }
|
||||||
|
.forEach(this::convert)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
|
||||||
*/
|
|
||||||
package ch.usi.inf.atelier.group1.html
|
|
||||||
|
|
||||||
import ch.usi.inf.atelier.group1.tex.TexDocument
|
|
||||||
import ch.usi.inf.atelier.group1.util.Log
|
|
||||||
import ch.usi.inf.atelier.group1.util.extensions.writeJekyllHeader
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class HtmlParser(path: String) {
|
|
||||||
private val file = JekyllHtmlFile(File(path))
|
|
||||||
private val document = Jsoup.parse(file.content)
|
|
||||||
private val texDocument = TexDocument()
|
|
||||||
|
|
||||||
fun parse(): String {
|
|
||||||
if (!file.isValid()) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
texDocument.start()
|
|
||||||
texDocument.writeJekyllHeader(file)
|
|
||||||
texDocument.beginDocument()
|
|
||||||
|
|
||||||
document.body().children().forEach { element -> parseToTex(element) }
|
|
||||||
|
|
||||||
texDocument.endDocument()
|
|
||||||
|
|
||||||
return texDocument.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseToTex(element: Element) {
|
|
||||||
val text = element.ownText()
|
|
||||||
|
|
||||||
// TODO: fix span elements inside the paragraph senteces (tag-less items)
|
|
||||||
|
|
||||||
texDocument.apply {
|
|
||||||
when (element.tagName()) {
|
|
||||||
TAG_BOLD -> addBold(text)
|
|
||||||
TAG_BR -> addBr()
|
|
||||||
TAG_CODE -> addCode(text)
|
|
||||||
TAG_H1 -> addSection(text)
|
|
||||||
TAG_H2 -> addSubSection(text)
|
|
||||||
TAG_H3, TAG_H4 -> addSubSubSection(text)
|
|
||||||
TAG_ITALICS -> addItalics(text)
|
|
||||||
TAG_LINK -> addLink(text, element.attr("href"))
|
|
||||||
TAG_P -> addParagraph(text)
|
|
||||||
TAG_PRE -> addPre(text)
|
|
||||||
TAG_UL -> element.parseList()
|
|
||||||
"", null -> addText(element.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Element.parseList() {
|
|
||||||
texDocument.apply {
|
|
||||||
beginList()
|
|
||||||
|
|
||||||
children().filter { TAG_LI == it.tagName() }
|
|
||||||
.forEach { e -> addListItem(e.text()) }
|
|
||||||
|
|
||||||
endList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG_BOLD = "b"
|
|
||||||
private const val TAG_BR = "br"
|
|
||||||
private const val TAG_CODE = "code"
|
|
||||||
private const val TAG_H1 = "h1"
|
|
||||||
private const val TAG_H2 = "h2"
|
|
||||||
private const val TAG_H3 = "h3"
|
|
||||||
private const val TAG_H4 = "h4"
|
|
||||||
private const val TAG_ITALICS = "i"
|
|
||||||
private const val TAG_LI = "li"
|
|
||||||
private const val TAG_LINK = "a"
|
|
||||||
private const val TAG_P = "p"
|
|
||||||
private const val TAG_PRE = "pre"
|
|
||||||
private const val TAG_UL = "ul"
|
|
||||||
}
|
|
||||||
}
|
|
261
bonus2/src/ch/usi/inf/atelier/group1/jekyll/HtmlToLatexWriter.kt
Normal file
261
bonus2/src/ch/usi/inf/atelier/group1/jekyll/HtmlToLatexWriter.kt
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
|
*/
|
||||||
|
package ch.usi.inf.atelier.group1.jekyll
|
||||||
|
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.parser.Parser
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
class HtmlToLatexWriter(private var content: String) {
|
||||||
|
private val document = StringBuilder()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the Latex file
|
||||||
|
* and insert the header
|
||||||
|
*/
|
||||||
|
fun start() {
|
||||||
|
document.clear()
|
||||||
|
|
||||||
|
insert(HEADER, afterLine = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin the document and insert the title
|
||||||
|
* and table of contents automatically
|
||||||
|
*/
|
||||||
|
fun beginDocument() {
|
||||||
|
insert("\\begin{document}", afterLine = true)
|
||||||
|
insert("\\maketitle", afterLine = true)
|
||||||
|
insert("\\tableofcontents\\")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End the document
|
||||||
|
*/
|
||||||
|
fun endDocument() {
|
||||||
|
insert(content)
|
||||||
|
insert("\\end{document}", afterLine = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a bold text in the document
|
||||||
|
*/
|
||||||
|
fun changeBold() {
|
||||||
|
content = content.replaceTag("<b>", "</b>", "\\textbf{", "}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <br> with a LaTeX newline
|
||||||
|
*/
|
||||||
|
fun changeBr() {
|
||||||
|
content = content.replaceTag("<br>", null, "\\\\", null)
|
||||||
|
.replaceTag("</br>", null, "\\\\", null)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <code> with LaTeX \texttt
|
||||||
|
*/
|
||||||
|
fun changeCode() {
|
||||||
|
content = content.replaceTag("<code>", "</code>", "\\texttt{", "}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <i> with LaTeX \emph
|
||||||
|
*/
|
||||||
|
fun changeItalics() {
|
||||||
|
content = content.replaceTag("<i>", "</i>", "\\emph{", "}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <a> with LaTeX footNote url
|
||||||
|
*/
|
||||||
|
fun changeLink() {
|
||||||
|
val pattern = Pattern.compile("<a href=\"(.*?)\"(.*?)>(.*?)</a>")
|
||||||
|
val matcher = pattern.matcher(content)
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
val text = matcher.group(3)
|
||||||
|
val url = matcher.group(1)
|
||||||
|
|
||||||
|
content = content.replace(matcher.group(0), LINK.format(url, text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <ul> and <ol> with LaTeX itemize
|
||||||
|
*/
|
||||||
|
fun changeList() {
|
||||||
|
content = content.replaceTag("<ul>", "</ul>", "\\begin{itemize}", "\\end{itemize}")
|
||||||
|
.replaceTag("<ol>", "</ol>", "\\begin{itemize}", "\\end{itemize}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <li> with LaTeX itemize item
|
||||||
|
*/
|
||||||
|
fun changeListItem() {
|
||||||
|
content = content.replaceTag("<li>", "</li>", "\\item ", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <pre> with LaTeX verbatim
|
||||||
|
*/
|
||||||
|
fun changeMono() {
|
||||||
|
content = content.replaceTag("<pre>", "</pre>", "\\begin{verbatim}", "\\end{verbatim}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <p>, empty <a>, <h4> and <h5> with LaTeX plain text
|
||||||
|
*/
|
||||||
|
fun changeParagraph() {
|
||||||
|
content = content.replaceTag("<h4>", "</h4>", "", "")
|
||||||
|
.replaceTag("<h5>", "</h5>", "", "")
|
||||||
|
.replaceTag("<p>", "</p>", "\n", "")
|
||||||
|
.replaceTag("<a>", "</a>", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <h1> with LaTeX \section
|
||||||
|
*/
|
||||||
|
fun changeSection() {
|
||||||
|
content = content.replaceTag("<h1>", "</h1>", "\\section{", "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <h2> with LaTeX \subsection
|
||||||
|
*/
|
||||||
|
fun changeSubSection() {
|
||||||
|
content = content.replaceTag("<h2>", "</h2>", "\\subsection{", "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <h3> with LaTeX \subsubsection
|
||||||
|
*/
|
||||||
|
fun changeSubSubSection() {
|
||||||
|
content = content.replaceTag("<h3>", "</h3>", "\\subsubsection{", "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <table> with LaTex tabular
|
||||||
|
*/
|
||||||
|
fun changeTable() {
|
||||||
|
val pattern = Pattern.compile("(?:<table>((?:.*?\\r?\\n?)*)</table>)+")
|
||||||
|
val matcher = pattern.matcher(content)
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
val document = Jsoup.parse(matcher.group(0), "", Parser.xmlParser())
|
||||||
|
val table = document.select("table")[0]
|
||||||
|
val rows = table.select("tr")
|
||||||
|
|
||||||
|
val columnsDump = ArrayList<String>()
|
||||||
|
var colCount = 0
|
||||||
|
|
||||||
|
for (row in rows) {
|
||||||
|
var columns = row.select("td")
|
||||||
|
if (columns.isEmpty()) {
|
||||||
|
// Maybe this is an header
|
||||||
|
columns = row.select("th")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colCount == 0) {
|
||||||
|
colCount = columns.size
|
||||||
|
}
|
||||||
|
|
||||||
|
val dump = StringBuilder()
|
||||||
|
columns.map { it.wholeText() }.forEach { dump.append("$it &") }
|
||||||
|
|
||||||
|
// Replace the last & with a LaTeX newLine
|
||||||
|
columnsDump.add(dump.removeSuffix("&").append("\\\\\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the LaTeX table
|
||||||
|
val latexTable = StringBuilder().run {
|
||||||
|
append("\\begin{table}[h]\n\\begin{tabular}{${"l".repeat(colCount)}}\n")
|
||||||
|
columnsDump.forEach { append(" $it") }
|
||||||
|
append("\\end{tabular}\n\\end{table}")
|
||||||
|
toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
content = content.replace(matcher.group(0), latexTable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace <ul> with LaTeX \underline
|
||||||
|
*/
|
||||||
|
fun changeUnderline() {
|
||||||
|
content = content.replaceTag("<u>", "</u>", "\\underline{", "}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an author to the document
|
||||||
|
*
|
||||||
|
* @param author the text being inserted
|
||||||
|
*/
|
||||||
|
fun addAuthor(author: String) {
|
||||||
|
insert(AUTHOR.format(author), true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a title to the document
|
||||||
|
*
|
||||||
|
* @param title the text being inserted
|
||||||
|
*/
|
||||||
|
fun addTitle(title: String) {
|
||||||
|
insert(TITLE.format(title), true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the html comments
|
||||||
|
*/
|
||||||
|
fun stripComments() {
|
||||||
|
content = content.replace(Regex("(?s)<!--.*?-->"), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert content into the document
|
||||||
|
*
|
||||||
|
* @param string the content being inserted
|
||||||
|
* @param preLine whether a newLine char should be inserted before the content
|
||||||
|
* @param afterLine whether a newLine char should be inserted after the content
|
||||||
|
*/
|
||||||
|
private fun insert(string: String, preLine: Boolean = false, afterLine: Boolean = false) {
|
||||||
|
document.apply {
|
||||||
|
if (preLine) {
|
||||||
|
append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
append(string)
|
||||||
|
|
||||||
|
if (afterLine) {
|
||||||
|
append("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.replaceTag(oldOpen: String, oldClose: String?,
|
||||||
|
newOpen: String, newClose: String?): String {
|
||||||
|
var replaced = replace(oldOpen, newOpen)
|
||||||
|
|
||||||
|
if (oldClose != null && newClose != null) {
|
||||||
|
replaced = replaced.replace(oldClose, newClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
return replaced
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CharSequence.append(append: String) = "${toString()}$append"
|
||||||
|
|
||||||
|
override fun toString() = document.toString()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val AUTHOR = "\\author{%1\$s}"
|
||||||
|
private const val TITLE = "\\title{%1\$s}"
|
||||||
|
private const val LINK = "\\underline{\\href{%1\$s}{%2\$s}}"
|
||||||
|
|
||||||
|
private const val HEADER =
|
||||||
|
"\\documentclass[hidelinks,12pt,a4paper,numbers=enddot]{scrartcl}\n\n" +
|
||||||
|
"\\usepackage[margin=2cm]{geometry}\n" +
|
||||||
|
"\\usepackage{hyperref}"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,22 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
package ch.usi.inf.atelier.group1.html
|
package ch.usi.inf.atelier.group1.jekyll
|
||||||
|
|
||||||
import ch.usi.inf.atelier.group1.util.extensions.getContent
|
import ch.usi.inf.atelier.group1.util.extensions.getContent
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
|
|
||||||
class JekyllHtmlFile(file: File) {
|
class JekyllPage(file: File) {
|
||||||
|
/**
|
||||||
|
* The jekyll header variables
|
||||||
|
*/
|
||||||
val header = HashMap<String, String>()
|
val header = HashMap<String, String>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jekyll html code
|
||||||
|
*/
|
||||||
val content: String
|
val content: String
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -28,12 +35,14 @@ class JekyllHtmlFile(file: File) {
|
||||||
isIteratingInHeader = HEADER_END != line
|
isIteratingInHeader = HEADER_END != line
|
||||||
|
|
||||||
if (isIteratingInHeader) {
|
if (isIteratingInHeader) {
|
||||||
|
// Import a jekyll variable
|
||||||
val values = line.split(":")
|
val values = line.split(":")
|
||||||
if (values.size == 2) {
|
if (values.size == 2) {
|
||||||
header[values[0]] = values[1].trim()
|
header[values[0]] = values[1].trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Import html code
|
||||||
contentBuilder.append(line).append('\n')
|
contentBuilder.append(line).append('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,10 +52,14 @@ class JekyllHtmlFile(file: File) {
|
||||||
content = contentBuilder.toString()
|
content = contentBuilder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the imported file actually had valid content
|
||||||
|
*
|
||||||
|
* @return true if the header and the content aren't empty
|
||||||
|
*/
|
||||||
fun isValid() = header.isNotEmpty() && content.isNotBlank()
|
fun isValid() = header.isNotEmpty() && content.isNotBlank()
|
||||||
|
|
||||||
override fun toString() =
|
override fun toString() = "Header:\n$header\nContent:\n$content"
|
||||||
"Header:\n$header\nContent:\n$content"
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val HEADER_START = "---"
|
private const val HEADER_START = "---"
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
|
||||||
*/
|
|
||||||
package ch.usi.inf.atelier.group1.tex
|
|
||||||
|
|
||||||
class TexDocument {
|
|
||||||
private val document = StringBuilder()
|
|
||||||
|
|
||||||
fun start() {
|
|
||||||
document.clear()
|
|
||||||
|
|
||||||
insert(HEADER, false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun beginDocument() {
|
|
||||||
insert("\\begin{document}", false, true)
|
|
||||||
insert("\\maketitle", false, true)
|
|
||||||
insert("\\tableofcontents", false, true)
|
|
||||||
insert("\\newpage", false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endDocument() {
|
|
||||||
insert("\\end{document}", false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addParagraph(content: String) {
|
|
||||||
if (content.isNotBlank()) {
|
|
||||||
insert(content, true, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addText(content: String) {
|
|
||||||
if (content.isNotBlank()) {
|
|
||||||
insert(content, false, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addSection(content: String) {
|
|
||||||
insert(SECTION.format(content, content.trim().toLowerCase()), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addSubSection(content: String) {
|
|
||||||
insert(SUB_SECTION.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addSubSubSection(content: String) {
|
|
||||||
insert(SUB_SUB_SECTION.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addBold(content: String) {
|
|
||||||
insert(BOLD.format(content), false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addItalics(content: String) {
|
|
||||||
insert(ITALICS.format(content), false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addCode(content: String) {
|
|
||||||
insert(CODE.format(content), false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addPre(content: String) {
|
|
||||||
insert(PRE.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addLink(content: String, url: String) {
|
|
||||||
insert(LINK.format(content, url), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun beginList() {
|
|
||||||
insert("\\begin{itemize}", false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endList() {
|
|
||||||
insert("\\end{itemize}", false, true)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addListItem(content: String) {
|
|
||||||
insert(LIST_ITEM.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addBr() {
|
|
||||||
insert("", false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setAuthor(content: String) {
|
|
||||||
insert(AUTHOR.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(content: String) {
|
|
||||||
insert(TITLE.format(content), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun insert(string: String, newLine: Boolean, endLine: Boolean) {
|
|
||||||
document.apply {
|
|
||||||
append(string)
|
|
||||||
if(newLine) {
|
|
||||||
append("\\\\")
|
|
||||||
}
|
|
||||||
if (endLine) {
|
|
||||||
append("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString() = document.toString()
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val AUTHOR = "\\author{%1\$s}\n"
|
|
||||||
private const val BOLD = "\\textbf{%1\$s}"
|
|
||||||
private const val CODE = "\\texttt{%1\$s}"
|
|
||||||
private const val ITALICS = "\\emph{%1\$s}"
|
|
||||||
private const val LINK = "\\emph{%1\$s} \\footnote{\\url{%2\$s}}"
|
|
||||||
private const val LIST_ITEM = "\\item %1\$s"
|
|
||||||
private const val PRE = "\n\\begin{verbatim}\n%1\$s\n\\end{verbatim}"
|
|
||||||
private const val SECTION = "\\section{%1\$s}\\label{%2\$s}"
|
|
||||||
private const val SUB_SECTION = "\\subsection{%1\$s}"
|
|
||||||
private const val SUB_SUB_SECTION = "\\subsubsection{%1\$s}"
|
|
||||||
private const val TITLE = "\\title{%1\$s}\n"
|
|
||||||
|
|
||||||
private const val HEADER =
|
|
||||||
"\\documentclass[hidelinks,12pt,a4paper,numbers=enddot]{scrartcl}\n\n" +
|
|
||||||
"\\usepackage[margin=2cm]{geometry}\n" +
|
|
||||||
"\\usepackage{hyperref}\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +1,28 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
package ch.usi.inf.atelier.group1.util
|
package ch.usi.inf.atelier.group1.util
|
||||||
|
|
||||||
import java.lang.Exception
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
object Log {
|
object Log {
|
||||||
|
|
||||||
fun e(message: String = "", exception: Exception) {
|
fun e(exception: Exception) {
|
||||||
e("$message: ${exception.message ?: "Unknown error"}")
|
print('E', exception.message ?: "Unknown error", true)
|
||||||
}
|
|
||||||
|
|
||||||
fun e(message: String) {
|
|
||||||
System.err.println(message)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun i(obj: Any) {
|
fun i(obj: Any) {
|
||||||
println(obj.toString())
|
print('I', obj.toString(), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun print(prefix: Char, message: String, isErr: Boolean) {
|
||||||
|
val time = SimpleDateFormat("yyyy-MM-dd hh:mm").format(Date())
|
||||||
|
|
||||||
|
if (isErr) {
|
||||||
|
System.err.println("$prefix $time\t$message")
|
||||||
|
} else {
|
||||||
|
System.out.println("$prefix $time\t$message")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
package ch.usi.inf.atelier.group1.util.extensions
|
package ch.usi.inf.atelier.group1.util.extensions
|
||||||
|
|
||||||
|
@ -9,6 +9,11 @@ import java.io.File
|
||||||
import java.io.FileReader
|
import java.io.FileReader
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of the file as String
|
||||||
|
*
|
||||||
|
* @return this File content
|
||||||
|
*/
|
||||||
fun File.getContent(): String {
|
fun File.getContent(): String {
|
||||||
val content = StringBuilder()
|
val content = StringBuilder()
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
|
||||||
*/
|
|
||||||
package ch.usi.inf.atelier.group1.util.extensions
|
|
||||||
|
|
||||||
import ch.usi.inf.atelier.group1.util.Log
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
fun String.toFile(): File? {
|
|
||||||
try {
|
|
||||||
File(this)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.e("Failed to open $this as File", e)
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun String.getClosingTag() = "</${substring(1, length)}"
|
|
|
@ -1,15 +1,39 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018. Bevilacqua Joey
|
* Copyright (c) 2018 Bevilacqua Joey.
|
||||||
*/
|
*/
|
||||||
package ch.usi.inf.atelier.group1.util.extensions
|
package ch.usi.inf.atelier.group1.util.extensions
|
||||||
|
|
||||||
import ch.usi.inf.atelier.group1.html.JekyllHtmlFile
|
import ch.usi.inf.atelier.group1.jekyll.HtmlToLatexWriter
|
||||||
import ch.usi.inf.atelier.group1.tex.TexDocument
|
import ch.usi.inf.atelier.group1.jekyll.JekyllPage
|
||||||
|
import ch.usi.inf.atelier.group1.util.Log
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileWriter
|
||||||
|
|
||||||
fun TexDocument.writeJekyllHeader(file: JekyllHtmlFile) {
|
/**
|
||||||
|
* Insert author and title from Jekyll file
|
||||||
|
*/
|
||||||
|
fun HtmlToLatexWriter.insertJekyllHeader(file: JekyllPage) {
|
||||||
val title = file.header["title"] ?: "Unknown title"
|
val title = file.header["title"] ?: "Unknown title"
|
||||||
val author = file.header["author"] ?: "Unknown author"
|
val author = file.header["author"] ?: "Unknown author"
|
||||||
|
|
||||||
setTitle(title)
|
addTitle(title)
|
||||||
setAuthor(author)
|
addAuthor(author)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun HtmlToLatexWriter.writeTo(path: String) {
|
||||||
|
val outDir = File("out", File(path).parent)
|
||||||
|
|
||||||
|
if (!outDir.exists()) {
|
||||||
|
outDir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
val file = File("out", path)
|
||||||
|
|
||||||
|
val writer = FileWriter(file, false)
|
||||||
|
|
||||||
|
Log.i("${file.path} created")
|
||||||
|
|
||||||
|
writer.write(toString())
|
||||||
|
writer.flush()
|
||||||
|
writer.close()
|
||||||
}
|
}
|
Loading…
Reference in a new issue