diff --git a/bonus2/.svnignore b/bonus2/.svnignore new file mode 100644 index 0000000..917d690 --- /dev/null +++ b/bonus2/.svnignore @@ -0,0 +1,13 @@ +*.iml +.idea +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +/lib +*.jar +/dist + diff --git a/bonus2/bonus2.iml b/bonus2/bonus2.iml new file mode 100644 index 0000000..b6a671e --- /dev/null +++ b/bonus2/bonus2.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/bonus2/build.gradle b/bonus2/build.gradle new file mode 100644 index 0000000..0cb9257 --- /dev/null +++ b/bonus2/build.gradle @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018. Bevilacqua Joey + */ + +buildscript { + ext.kotlin_version = '1.3.0' + + repositories { + mavenCentral() + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.0' + } +} + +apply plugin: 'kotlin' +apply plugin: 'com.github.johnrengelman.shadow' +apply plugin: 'application' + +defaultTasks 'run' + +repositories { + mavenCentral() +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'org.jsoup:jsoup:1.11.3' +} + +mainClassName = 'ch.usi.inf.atelier.group1.Main' + +sourceSets { + main.java.srcDirs += 'src' +} + +task sourcesJar(type: Jar) { + classifier = 'sources' + from 'src' +} + +jar { + manifest { + attributes 'Main-Class': 'ch.usi.inf.atelier.group1.MainKt' + } +} + +shadowJar { + baseName = 'bonus2' + classifier = null + version = null +} diff --git a/bonus2/res/test.html b/bonus2/res/test.html new file mode 100644 index 0000000..0170136 --- /dev/null +++ b/bonus2/res/test.html @@ -0,0 +1,59 @@ +--- +layout: page +category-title: Basic commands +category-page: basic +tags: directory change navigate +author: Alessandro Marinelli +title: cd +previous-page: pages/cmd/basic/open.html +next-page: pages/cmd/basic/ls.html +--- + +

+The cd command is used to change the working directory
+The name stands for Change Directory.
+ +The default cd command syntax is: + +

+cd [flags] [path]
+
+ +Where [flags] are the cd flags, read below for more info,and [path] is the +path (absolute or relative), of the directory which we want to make as working directory.

+ +

Change the working directory

+Let's see how to use the command cd in order to change the working directory + +
+pwd
+    ~
+cd Desktop/multimedia
+pwd
+    ~/Desktop/multimedia
+
+ +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.
+ +Notice: If you want to move to a directory which is not contained in the +current working directory, you MUST use the absolute path. + + +

Header 1

+ +

Header 2

+ +

Header 4

+ + + +

diff --git a/bonus2/src/ch/usi/inf/atelier/group1/Main.kt b/bonus2/src/ch/usi/inf/atelier/group1/Main.kt new file mode 100644 index 0000000..6b8688d --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/Main.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018. Bevilacqua Joey + */ +package ch.usi.inf.atelier.group1 + +import ch.usi.inf.atelier.group1.html.HtmlParser + +object Main { + + @JvmStatic + fun main(args: Array) { + + for (arg in args) { + println(HtmlParser(arg).parse()) + } + } +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/html/HtmlParser.kt b/bonus2/src/ch/usi/inf/atelier/group1/html/HtmlParser.kt new file mode 100644 index 0000000..2cfa3cf --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/html/HtmlParser.kt @@ -0,0 +1,83 @@ +/* + * 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" + } +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/html/JekyllHtmlFile.kt b/bonus2/src/ch/usi/inf/atelier/group1/html/JekyllHtmlFile.kt new file mode 100644 index 0000000..0cc09f0 --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/html/JekyllHtmlFile.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018. Bevilacqua Joey + */ +package ch.usi.inf.atelier.group1.html + +import ch.usi.inf.atelier.group1.util.extensions.getContent +import java.io.BufferedReader +import java.io.File +import java.io.StringReader + +class JekyllHtmlFile(file: File) { + val header = HashMap() + val content: String + + init { + val fileContent = file.getContent() + val contentBuilder = StringBuilder() + + var isIteratingInHeader = false + var line: String? = "" + + val reader = BufferedReader(StringReader(fileContent)) + + while (line != null) { + if (!isIteratingInHeader && HEADER_START == line) { + isIteratingInHeader = true + } else if (isIteratingInHeader) { + isIteratingInHeader = HEADER_END != line + + if (isIteratingInHeader) { + val values = line.split(":") + if (values.size == 2) { + header[values[0]] = values[1].trim() + } + } + } else { + contentBuilder.append(line).append('\n') + } + + line = reader.readLine() + } + + content = contentBuilder.toString() + } + + fun isValid() = header.isNotEmpty() && content.isNotBlank() + + override fun toString() = + "Header:\n$header\nContent:\n$content" + + companion object { + private const val HEADER_START = "---" + private const val HEADER_END = "---" + } +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/tex/TexDocument.kt b/bonus2/src/ch/usi/inf/atelier/group1/tex/TexDocument.kt new file mode 100644 index 0000000..75dead2 --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/tex/TexDocument.kt @@ -0,0 +1,128 @@ +/* + * 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" + + } +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/util/Log.kt b/bonus2/src/ch/usi/inf/atelier/group1/util/Log.kt new file mode 100644 index 0000000..88ad775 --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/util/Log.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018. Bevilacqua Joey + */ +package ch.usi.inf.atelier.group1.util + +import java.lang.Exception + +object Log { + + fun e(message: String = "", exception: Exception) { + e("$message: ${exception.message ?: "Unknown error"}") + } + + fun e(message: String) { + System.err.println(message) + } + + fun i(obj: Any) { + println(obj.toString()) + } +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/File.kt b/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/File.kt new file mode 100644 index 0000000..af437dd --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/File.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018. Bevilacqua Joey + */ +package ch.usi.inf.atelier.group1.util.extensions + +import ch.usi.inf.atelier.group1.util.Log +import java.io.BufferedReader +import java.io.File +import java.io.FileReader +import java.io.IOException + +fun File.getContent(): String { + val content = StringBuilder() + try { + val reader = BufferedReader(FileReader(this)) + var line: String? = "" + + while (line != null) { + content.append(line) + .append('\n') + line = reader.readLine() + } + } catch (e: IOException) { + Log.e(exception = e) + } + + return content.toString() +} \ No newline at end of file diff --git a/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/String.kt b/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/String.kt new file mode 100644 index 0000000..c39e71f --- /dev/null +++ b/bonus2/src/ch/usi/inf/atelier/group1/util/extensions/String.kt @@ -0,0 +1,21 @@ +/* + * 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() = "