more btex tests

This commit is contained in:
minjaesong
2024-04-25 01:29:32 +09:00
parent 76dd9a98e4
commit f154756439
5 changed files with 433 additions and 63 deletions

View File

@@ -9,41 +9,61 @@
<manuscript>
<chapter>What Is a Book</chapter>
<p>This example book is designed to give you the exampe of the Book Language.</p>
<p>This example book is designed to give you the example of the Book Language.</p>
<section>What Really Is a Book</section>
<p>A book is a collection of texts printed in a special way that allows them to be read easily, with enumerable pages and insertion of other helpful resources, such as illustrations and hyperlinks.</p>
<p>A book is a collection of texts printed in a special way that allows them to be read easily, with
enumerable pages and insertion of other helpful resources, such as illustrations and hyperlinks.</p>
<newpage />
<fullpagebox>
<span colour="grey">
<p>this page is intentionally left blank</p>
</span>
<p><span colour="grey">
this page is intentionally left blank
</span></p>
</fullpagebox>
<chapter>Writing Book Using Pen and Papers</chapter>
<p>If you open a book on a writing table, you will be welcomed with a toolbar used to put other book elements, such as chapters, sections.</p>
<p><index id="pen and paper" />If you open a book on a writing table, you will be welcomed with a
toolbar used to put other book elements, such as chapters, sections.</p>
<chapter>Writing Book Using Typewriter</chapter>
<p>Typewriters can only write single style of font, therefore chapters and sections are not available.</p>
<p><index id="typewriter" />Typewriters can only write single style of font, therefore chapters and
sections are not available.</p>
<chapter>Writing Book using Computer</chapter>
<p>Writing book using a computer requires a use of the Book Typesetting Engine Extended, or <BTeX /></p>
<p>Writing book using a computer requires a use of the Book Typesetting Engine Extended, or <btex /></p>
<section>Full Control of the Shape</section>
<p>With <BTeX /> you can fully control how your publishing would look like, from a pile of papers that look like they have been typed out using typewriter, a pile of papers but a fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.</p>
<p><index id="btex language" />With <btex /> you can fully control how your publishing would look like,
from a pile of papers that look like they have been typed out using typewriter, a pile of papers but a
fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.</p>
<p>This style is controlled using the <code>cover</code> attribute on the root tag, with following values: <code>typewriter</code>, <code>printout</code>, <code>hardcover</code></p>
<p><index id="cover" />This style is controlled using the <code>cover</code> attribute on the root tag,
with following values: <code>typewriter</code>, <code>printout</code>, <code>hardcover</code></p>
<p>Typewriter and Printout are considered not bound and readers will only see one page at a time, while Hardcover is considered bound and two pages are presented to the readers.</p>
<p>Typewriter and Printout are considered not bound and readers will only see one page at a time,
while Hardcover is considered bound and two pages are presented to the readers.</p>
</manuscript>
<indexpage><tableofindices /></indexpage>
</btexdoc>

Binary file not shown.

View File

@@ -1,10 +1,8 @@
package net.torvald.terrarum.btex
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.App
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarumsansbitmap.MovableType
@@ -18,9 +16,9 @@ class BTeXDocument {
var papersize = "standard"
var pageWidth = 420
var lineHeight = 24
var lineHeightInPx = 24
var pageLines = 25
var pageHeight = pageLines * lineHeight
var pageHeight = pageLines * lineHeightInPx
companion object {
val DEFAULT_PAGE_BACK = Color(0xe1e1d7ff.toInt())
@@ -29,14 +27,26 @@ class BTeXDocument {
private val pages = ArrayList<BTeXPage>()
val currentPage: Int
get() = pages.size - 1
var currentLine: Int = 0
private set
fun addNewPage(back: Color = DEFAULT_PAGE_BACK) {
pages.add(BTeXPage(back, pageWidth, pageHeight))
currentLine = 0
}
/**
* Appends draw call to the list. The draw call must be prepared manually so that they would not overflow.
* Use `addNewPage` to append the overflowing text to the next page.
*
* `currentLine` *will* be updated automatically.
*/
fun appendDrawCall(drawCall: BTeXDrawCall) {
pages.last().appendDrawCall(drawCall)
currentLine += drawCall.lineCount
}
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
@@ -64,21 +74,37 @@ class BTeXPage(
}
}
data class MovableTypeDrawCall(val movableType: MovableType, val rowStart: Int, val rowEnd: Int) {
fun draw(batch: SpriteBatch, x: Float, y: Float) {
interface BTeXTextDrawCall {
val rowStart: Int
val rowEnd: Int
fun draw(batch: SpriteBatch, x: Float, y: Float)
}
data class MovableTypeDrawCall(val movableType: MovableType, override val rowStart: Int, override val rowEnd: Int): BTeXTextDrawCall {
override fun draw(batch: SpriteBatch, x: Float, y: Float) {
movableType.draw(batch, x, y, rowStart, rowEnd)
}
}
/*data class RaggedLeftDrawCall(val raggedType: RaggedType, override val rowStart: Int, override val rowEnd: Int): BTeXTextDrawCall {
override fun draw(batch: SpriteBatch, x: Float, y: Float) {
raggedType.draw(batch, x, y, rowStart, rowEnd)
}
}*/
class BTeXDrawCall(
val posX: Int,
val posY: Int,
val posX: Int, // position relative to the page start (excluding page margin)
val posY: Int, // position relative to the page start (excluding page margin)
val theme: String,
val colour: Color,
val text: MovableTypeDrawCall? = null,
val text: BTeXTextDrawCall? = null,
val texture: TextureRegion? = null,
) {
init {
if (text != null && texture != null) throw IllegalArgumentException("Text and Texture are both non-null")
}
fun draw(batch: SpriteBatch, x: Int, y: Int) {
val px = (posX + x).toFloat()
val py = (posY + y).toFloat()
@@ -98,4 +124,9 @@ class BTeXDrawCall(
else throw Error("Text and Texture are both non-null")
}
internal val lineCount = if (text != null)
text.rowEnd - text.rowStart
else
TODO()
}

View File

@@ -4,7 +4,11 @@ import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import net.torvald.terrarum.App
import net.torvald.terrarum.btex.BTeXDocument
import net.torvald.terrarum.btex.BTeXDrawCall
import net.torvald.terrarum.btex.MovableTypeDrawCall
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarumsansbitmap.MovableType
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap
import org.xml.sax.Attributes
import org.xml.sax.InputSource
import org.xml.sax.helpers.DefaultHandler
@@ -20,6 +24,9 @@ import kotlin.reflect.full.findAnnotation
*/
object BTeXParser {
internal val textTags = hashSetOf("P", "TITLE", "AUTHOR", "EDITION", "CHAPTER", "SECTION")
internal val textDecorTags = hashSetOf("SPAN", "CODE")
operator fun invoke(file: FileHandle) = invoke(file.file())
operator fun invoke(file: File): BTeXDocument {
@@ -39,7 +46,7 @@ object BTeXParser {
internal class BTeXHandler(val doc: BTeXDocument) : DefaultHandler() {
private val DEFAULT_FONTCOL = Color(0x222222ff)
private val LINE_HEIGHT = doc.lineHeight
private val LINE_HEIGHT = doc.lineHeightInPx
private var cover = ""
private var inner = ""
@@ -56,7 +63,7 @@ object BTeXParser {
private val tagStack = ArrayList<String>() // index zero should be "btex"
private var currentTheme = ""
private var spanColour: String? = null
@@ -66,6 +73,8 @@ object BTeXParser {
private val elemOpeners: HashMap<String, KFunction<*>> = HashMap()
private val elemClosers: HashMap<String, KFunction<*>> = HashMap()
private val paragraphBuffer = StringBuilder()
init {
BTeXHandler::class.declaredFunctions.filter { it.findAnnotation<OpenTag>() != null }.forEach {
println("Tag opener: ${it.name}")
@@ -101,14 +110,21 @@ object BTeXParser {
}
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
val tag = qName; if (tagStack.isEmpty() && tag.lowercase() != "btexdoc") throw BTeXParsingException("Document is not BTeX")
tagStack.add(tag)
val tag = qName
if (tagStack.isEmpty() && tag.lowercase() != "btexdoc") throw BTeXParsingException("Document is not BTeX")
val theTag = tag.uppercase()
if (tagStack.isNotEmpty() && tagStack.any { textTags.contains(it) } && textTags.contains(theTag))
throw IllegalStateException("Text tag '$theTag' used inside of text tags (tag stack is ${tagStack.joinToString()})")
if (tagStack.isNotEmpty() && !textTags.contains(tagStack.last()) && textDecorTags.contains(theTag))
throw IllegalStateException("Text decoration tag '$theTag' used outside of a text tag (tag stack is ${tagStack.joinToString()})")
tagStack.add(theTag)
val attribs = HashMap<String, String>().also {
it.putAll((0 until attributes.length).map { attributes.getQName(it) to attributes.getValue(it) })
}
val theTag = tag.uppercase()
elemOpeners["processElem$theTag"].let {
if (it == null)
@@ -123,7 +139,7 @@ object BTeXParser {
}
}
// printdbg("Start element \t($tag)")
// printdbg("Start element \t($theTag)")
}
override fun endElement(uri: String, localName: String, qName: String) {
@@ -147,8 +163,9 @@ object BTeXParser {
val str =
String(ch.sliceArray(start until start + length)).replace('\n', ' ').replace(Regex(" +"), " ")//.trim()
if (str.isNotBlank()) {
printdbg("Characters \t\"$str\"")
if (str.isNotEmpty()) {
// printdbg("Characters \t\"$str\"")
paragraphBuffer.append(str)
}
}
@@ -170,16 +187,212 @@ object BTeXParser {
typeY += h
}
private lateinit var testFont: TerrarumSansBitmap
private fun getFont() = when (cover) {
"typewriter" -> TODO()
else -> App.fontGame
else -> App.fontGame ?: let {
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR)
testFont
}
}
private fun getSpanColour(): Color = spanColourMap.getOrDefault(spanColour, DEFAULT_FONTCOL)
private val hexColRegexRGBshort = Regex("#[0-9a-fA-F]{3,3}")
private val hexColRegexRGB = Regex("#[0-9a-fA-F]{6,6}")
private fun getSpanColour(): Color = if (spanColour == null) DEFAULT_FONTCOL
else if (spanColour!!.matches(hexColRegexRGB)) {
val rs = spanColour!!.substring(1,3)
val gs = spanColour!!.substring(3,5)
val bs = spanColour!!.substring(5,7)
val r = rs.toInt(16) / 255f
val g = gs.toInt(16) / 255f
val b = bs.toInt(16) / 255f
Color(r, g, b, 1f)
}
else if (spanColour!!.matches(hexColRegexRGBshort)) {
val rs = spanColour!!.substring(1,2)
val gs = spanColour!!.substring(2,3)
val bs = spanColour!!.substring(3,4)
val r = rs.toInt(16) / 15f
val g = gs.toInt(16) / 15f
val b = bs.toInt(16) / 15f
Color(r, g, b, 1f)
}
else
spanColourMap.getOrDefault(spanColour, DEFAULT_FONTCOL)
// list of CSS named colours (list supports up to CSS Colors Level 4)
private val spanColourMap = hashMapOf(
"grey" to Color.LIGHT_GRAY
"black" to Color(0x000000ff.toInt()),
"silver" to Color(0xc0c0c0ff.toInt()),
"gray" to Color(0x808080ff.toInt()),
"white" to Color(0xffffffff.toInt()),
"maroon" to Color(0x800000ff.toInt()),
"red" to Color(0xff0000ff.toInt()),
"purple" to Color(0x800080ff.toInt()),
"fuchsia" to Color(0xff00ffff.toInt()),
"green" to Color(0x008000ff.toInt()),
"lime" to Color(0x00ff00ff.toInt()),
"olive" to Color(0x808000ff.toInt()),
"yellow" to Color(0xffff00ff.toInt()),
"navy" to Color(0x000080ff.toInt()),
"blue" to Color(0x0000ffff.toInt()),
"teal" to Color(0x008080ff.toInt()),
"aqua" to Color(0x00ffffff.toInt()),
"aliceblue" to Color(0xf0f8ffff.toInt()),
"antiquewhite" to Color(0xfaebd7ff.toInt()),
"aqua" to Color(0x00ffffff.toInt()),
"aquamarine" to Color(0x7fffd4ff.toInt()),
"azure" to Color(0xf0ffffff.toInt()),
"beige" to Color(0xf5f5dcff.toInt()),
"bisque" to Color(0xffe4c4ff.toInt()),
"black" to Color(0x000000ff.toInt()),
"blanchedalmond" to Color(0xffebcdff.toInt()),
"blue" to Color(0x0000ffff.toInt()),
"blueviolet" to Color(0x8a2be2ff.toInt()),
"brown" to Color(0xa52a2aff.toInt()),
"burlywood" to Color(0xdeb887ff.toInt()),
"cadetblue" to Color(0x5f9ea0ff.toInt()),
"chartreuse" to Color(0x7fff00ff.toInt()),
"chocolate" to Color(0xd2691eff.toInt()),
"coral" to Color(0xff7f50ff.toInt()),
"cornflowerblue" to Color(0x6495edff.toInt()),
"cornsilk" to Color(0xfff8dcff.toInt()),
"crimson" to Color(0xdc143cff.toInt()),
"cyan" to Color(0x00ffffff.toInt()),
"darkblue" to Color(0x00008bff.toInt()),
"darkcyan" to Color(0x008b8bff.toInt()),
"darkgoldenrod" to Color(0xb8860bff.toInt()),
"darkgray" to Color(0xa9a9a9ff.toInt()),
"darkgreen" to Color(0x006400ff.toInt()),
"darkgrey" to Color(0xa9a9a9ff.toInt()),
"darkkhaki" to Color(0xbdb76bff.toInt()),
"darkmagenta" to Color(0x8b008bff.toInt()),
"darkolivegreen" to Color(0x556b2fff.toInt()),
"darkorange" to Color(0xff8c00ff.toInt()),
"darkorchid" to Color(0x9932ccff.toInt()),
"darkred" to Color(0x8b0000ff.toInt()),
"darksalmon" to Color(0xe9967aff.toInt()),
"darkseagreen" to Color(0x8fbc8fff.toInt()),
"darkslateblue" to Color(0x483d8bff.toInt()),
"darkslategray" to Color(0x2f4f4fff.toInt()),
"darkslategrey" to Color(0x2f4f4fff.toInt()),
"darkturquoise" to Color(0x00ced1ff.toInt()),
"darkviolet" to Color(0x9400d3ff.toInt()),
"deeppink" to Color(0xff1493ff.toInt()),
"deepskyblue" to Color(0x00bfffff.toInt()),
"dimgray" to Color(0x696969ff.toInt()),
"dimgrey" to Color(0x696969ff.toInt()),
"dodgerblue" to Color(0x1e90ffff.toInt()),
"firebrick" to Color(0xb22222ff.toInt()),
"floralwhite" to Color(0xfffaf0ff.toInt()),
"forestgreen" to Color(0x228b22ff.toInt()),
"fuchsia" to Color(0xff00ffff.toInt()),
"gainsboro" to Color(0xdcdcdcff.toInt()),
"ghostwhite" to Color(0xf8f8ffff.toInt()),
"gold" to Color(0xffd700ff.toInt()),
"goldenrod" to Color(0xdaa520ff.toInt()),
"gray" to Color(0x808080ff.toInt()),
"green" to Color(0x008000ff.toInt()),
"greenyellow" to Color(0xadff2fff.toInt()),
"grey" to Color(0x808080ff.toInt()),
"honeydew" to Color(0xf0fff0ff.toInt()),
"hotpink" to Color(0xff69b4ff.toInt()),
"indianred" to Color(0xcd5c5cff.toInt()),
"indigo" to Color(0x4b0082ff.toInt()),
"ivory" to Color(0xfffff0ff.toInt()),
"khaki" to Color(0xf0e68cff.toInt()),
"lavender" to Color(0xe6e6faff.toInt()),
"lavenderblush" to Color(0xfff0f5ff.toInt()),
"lawngreen" to Color(0x7cfc00ff.toInt()),
"lemonchiffon" to Color(0xfffacdff.toInt()),
"lightblue" to Color(0xadd8e6ff.toInt()),
"lightcoral" to Color(0xf08080ff.toInt()),
"lightcyan" to Color(0xe0ffffff.toInt()),
"lightgoldenrodyellow" to Color(0xfafad2ff.toInt()),
"lightgray" to Color(0xd3d3d3ff.toInt()),
"lightgreen" to Color(0x90ee90ff.toInt()),
"lightgrey" to Color(0xd3d3d3ff.toInt()),
"lightpink" to Color(0xffb6c1ff.toInt()),
"lightsalmon" to Color(0xffa07aff.toInt()),
"lightseagreen" to Color(0x20b2aaff.toInt()),
"lightskyblue" to Color(0x87cefaff.toInt()),
"lightslategray" to Color(0x778899ff.toInt()),
"lightslategrey" to Color(0x778899ff.toInt()),
"lightsteelblue" to Color(0xb0c4deff.toInt()),
"lightyellow" to Color(0xffffe0ff.toInt()),
"lime" to Color(0x00ff00ff.toInt()),
"limegreen" to Color(0x32cd32ff.toInt()),
"linen" to Color(0xfaf0e6ff.toInt()),
"magenta" to Color(0xff00ffff.toInt()),
"maroon" to Color(0x800000ff.toInt()),
"mediumaquamarine" to Color(0x66cdaaff.toInt()),
"mediumblue" to Color(0x0000cdff.toInt()),
"mediumorchid" to Color(0xba55d3ff.toInt()),
"mediumpurple" to Color(0x9370dbff.toInt()),
"mediumseagreen" to Color(0x3cb371ff.toInt()),
"mediumslateblue" to Color(0x7b68eeff.toInt()),
"mediumspringgreen" to Color(0x00fa9aff.toInt()),
"mediumturquoise" to Color(0x48d1ccff.toInt()),
"mediumvioletred" to Color(0xc71585ff.toInt()),
"midnightblue" to Color(0x191970ff.toInt()),
"mintcream" to Color(0xf5fffaff.toInt()),
"mistyrose" to Color(0xffe4e1ff.toInt()),
"moccasin" to Color(0xffe4b5ff.toInt()),
"navajowhite" to Color(0xffdeadff.toInt()),
"navy" to Color(0x000080ff.toInt()),
"oldlace" to Color(0xfdf5e6ff.toInt()),
"olive" to Color(0x808000ff.toInt()),
"olivedrab" to Color(0x6b8e23ff.toInt()),
"orange" to Color(0xffa500ff.toInt()),
"orangered" to Color(0xff4500ff.toInt()),
"orchid" to Color(0xda70d6ff.toInt()),
"palegoldenrod" to Color(0xeee8aaff.toInt()),
"palegreen" to Color(0x98fb98ff.toInt()),
"paleturquoise" to Color(0xafeeeeff.toInt()),
"palevioletred" to Color(0xdb7093ff.toInt()),
"papayawhip" to Color(0xffefd5ff.toInt()),
"peachpuff" to Color(0xffdab9ff.toInt()),
"peru" to Color(0xcd853fff.toInt()),
"pink" to Color(0xffc0cbff.toInt()),
"plum" to Color(0xdda0ddff.toInt()),
"powderblue" to Color(0xb0e0e6ff.toInt()),
"purple" to Color(0x800080ff.toInt()),
"rebeccapurple" to Color(0x663399ff.toInt()),
"red" to Color(0xff0000ff.toInt()),
"rosybrown" to Color(0xbc8f8fff.toInt()),
"royalblue" to Color(0x4169e1ff.toInt()),
"saddlebrown" to Color(0x8b4513ff.toInt()),
"salmon" to Color(0xfa8072ff.toInt()),
"sandybrown" to Color(0xf4a460ff.toInt()),
"seagreen" to Color(0x2e8b57ff.toInt()),
"seashell" to Color(0xfff5eeff.toInt()),
"sienna" to Color(0xa0522dff.toInt()),
"silver" to Color(0xc0c0c0ff.toInt()),
"skyblue" to Color(0x87ceebff.toInt()),
"slateblue" to Color(0x6a5acdff.toInt()),
"slategray" to Color(0x708090ff.toInt()),
"slategrey" to Color(0x708090ff.toInt()),
"snow" to Color(0xfffafaff.toInt()),
"springgreen" to Color(0x00ff7fff.toInt()),
"steelblue" to Color(0x4682b4ff.toInt()),
"tan" to Color(0xd2b48cff.toInt()),
"teal" to Color(0x008080ff.toInt()),
"thistle" to Color(0xd8bfd8ff.toInt()),
"tomato" to Color(0xff6347ff.toInt()),
"transparent" to Color(0),
"turquoise" to Color(0x40e0d0ff.toInt()),
"violet" to Color(0xee82eeff.toInt()),
"wheat" to Color(0xf5deb3ff.toInt()),
"white" to Color(0xffffffff.toInt()),
"whitesmoke" to Color(0xf5f5f5ff.toInt()),
"yellow" to Color(0xffff00ff.toInt()),
"yellowgreen" to Color(0x9acd32ff.toInt())
)
private val pageWidthMap = hashMapOf(
@@ -239,14 +452,35 @@ object BTeXParser {
// TODO add post-parsing hook to the handler
}
@OpenTag // reflective access is impossible with 'private'
fun processElemBTEX(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
handler.paragraphBuffer.append("BTeX")
}
@OpenTag // reflective access is impossible with 'private'
fun processElemBR(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
fun processElemCOVER(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
doc.addNewPage(Color(0x6f4a45ff))
}
@OpenTag // reflective access is impossible with 'private'
fun processElemTOC(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
doc.addNewPage()
}
@OpenTag // reflective access is impossible with 'private'
fun processElemMANUSCRIPT(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
doc.addNewPage()
}
@OpenTag // reflective access is impossible with 'private'
fun processElemBR(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
handler.paragraphBuffer.append("\n")
}
@OpenTag // reflective access is impossible with 'private'
@@ -256,12 +490,63 @@ object BTeXParser {
@OpenTag // reflective access is impossible with 'private'
fun processElemP(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap<String, String>) {
}
@CloseTag // reflective access is impossible with 'private'
fun closeElemP(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String) {
printdbg("Par: ${handler.paragraphBuffer}")
val font = getFont()
val slugs = MovableType(font, handler.paragraphBuffer.toString(), doc.pageWidth)
var remainder = doc.pageLines - doc.currentLine
var slugHeight = slugs.height
var linesOut = 0
if (slugHeight > remainder) {
val subset = linesOut to linesOut + remainder
val drawCall = BTeXDrawCall(
0,
remainder * doc.pageLines,
handler.currentTheme,
handler.getSpanColour(),
MovableTypeDrawCall(slugs, subset.first, subset.second)
)
doc.appendDrawCall(drawCall)
linesOut += remainder
slugHeight -= remainder
doc.addNewPage()
}
while (slugHeight > 0) {
remainder = minOf(slugHeight, doc.pageLines)
val subset = linesOut to linesOut + remainder
val drawCall = BTeXDrawCall(
0,
0,
handler.currentTheme,
handler.getSpanColour(),
MovableTypeDrawCall(slugs, subset.first, subset.second)
)
doc.appendDrawCall(drawCall)
linesOut += remainder
slugHeight -= remainder
if (remainder == doc.pageLines) {
doc.addNewPage()
}
}
handler.paragraphBuffer.clear()
}
@OpenTag // reflective access is impossible with 'private'
@@ -275,6 +560,7 @@ object BTeXParser {
fun closeElemSPAN(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String) {
spanColour = null
}
}

View File

@@ -1,18 +1,18 @@
package net.torvald.terrarum.tests
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.badlogic.gdx.graphics.glutils.ShaderProgram
import net.torvald.btex.BTeXParser
import org.xml.sax.Attributes
import org.xml.sax.HandlerBase
import org.xml.sax.helpers.DefaultHandler
import java.io.ByteArrayInputStream
import java.io.InputStream
import javax.xml.parsers.SAXParserFactory
import net.torvald.terrarum.btex.BTeXDocument
/**
* Created by minjaesong on 2023-10-28.
*/
fun main() {
class BTeXTest : ApplicationAdapter() {
val csiR = "\u001B[31m"
val csiG = "\u001B[32m"
val csi0 = "\u001B[m"
@@ -27,54 +27,87 @@ fun main() {
<toc><tableofcontents /></toc>
<manuscript>
<chapter>What Is a Book</chapter>
<p>This example book is designed to give you the exampe of the Book Language.</p>
<p>This example book is designed to give you the example of the Book Language.</p>
<section>What Really Is a Book</section>
<p>A book is a collection of texts printed in a special way that allows them to be read easily, with
enumerable pages and insertion of other helpful resources, such as illustrations and hyperlinks.</p>
enumerable pages and insertion of other helpful resources, such as illustrations and hyperlinks.</p>
<newpage />
<fullpagebox>
<span colour="grey">
<p>this page is intentionally left blank</p>
</span>
<p><span colour="grey">
this page is intentionally left blank
</span></p>
</fullpagebox>
<chapter>Writing Book Using Pen and Papers</chapter>
<p>If you open a book on a writing table, you will be welcomed with a toolbar used to put other book
elements, such as chapters, sections.</p>
<p><index id="pen and paper" />If you open a book on a writing table, you will be welcomed with a
toolbar used to put other book elements, such as chapters, sections.</p>
<chapter>Writing Book Using Typewriter</chapter>
<p>Typewriters can only write single style of font, therefore chapters and sections are not available.</p>
<p><index id="typewriter" />Typewriters can only write single style of font, therefore chapters and
sections are not available.</p>
<chapter>Writing Book using Computer</chapter>
<p>Writing book using a computer requires a use of the Book Typesetting Engine Extended, or <btex /></p>
<section>Full Control of the Shape</section>
<p>With <btex /> you can fully control how your publishing would look like, from a pile of papers that
look like they have been typed out using typewriter, a pile of papers but a fully-featured printouts that
have illustrations in it, to a fully-featured hardcover book.</p>
<p><index id="btex language" />With <btex /> you can fully control how your publishing would look like,
from a pile of papers that look like they have been typed out using typewriter, a pile of papers but a
fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.</p>
<p>This style is controlled using the <code>cover</code> attribute on the root tag, with following
values: <code>typewriter</code>, <code>printout</code>, <code>hardcover</code></p>
<p><index id="cover" />This style is controlled using the <code>cover</code> attribute on the root tag,
with following values: <code>typewriter</code>, <code>printout</code>, <code>hardcover</code></p>
<p>Typewriter and Printout are considered not bound and readers will only see one page at a time,
while Hardcover is considered bound and two pages are presented to the readers.</p>
while Hardcover is considered bound and two pages are presented to the readers.</p>
</manuscript>
</btexdoc>
<indexpage><tableofindices /></indexpage>
</btexdoc>
"""
val doku = BTeXParser(tex)
private lateinit var document: BTeXDocument
override fun create() {
document = BTeXParser.invoke(tex)
}
}
fun main() {
ShaderProgram.pedantic = false
val appConfig = Lwjgl3ApplicationConfiguration()
appConfig.useVsync(false)
appConfig.setResizable(false)
appConfig.setWindowedMode(1280, 720)
appConfig.setForegroundFPS(60)
appConfig.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL30, 3, 2)
Lwjgl3Application(BTeXTest(), appConfig)
}