mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Implement bold and italics 📜
This commit is contained in:
parent
a34d725000
commit
3b4b55c59e
@ -30,6 +30,8 @@ pub struct Engine<'t> {
|
|||||||
current_text: String,
|
current_text: String,
|
||||||
current_line_width: Size,
|
current_line_width: Size,
|
||||||
current_max_vertical_move: Size,
|
current_max_vertical_move: Size,
|
||||||
|
bold: bool,
|
||||||
|
italic: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Engine<'t> {
|
impl<'t> Engine<'t> {
|
||||||
@ -44,6 +46,8 @@ impl<'t> Engine<'t> {
|
|||||||
current_text: String::new(),
|
current_text: String::new(),
|
||||||
current_line_width: Size::zero(),
|
current_line_width: Size::zero(),
|
||||||
current_max_vertical_move: Size::zero(),
|
current_max_vertical_move: Size::zero(),
|
||||||
|
italic: false,
|
||||||
|
bold: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +61,12 @@ impl<'t> Engine<'t> {
|
|||||||
match node {
|
match node {
|
||||||
Node::Word(word) => self.write_word(word)?,
|
Node::Word(word) => self.write_word(word)?,
|
||||||
Node::Space => self.write_space()?,
|
Node::Space => self.write_space()?,
|
||||||
Node::Newline => (),
|
Node::Newline => {},
|
||||||
Node::ToggleItalics | Node::ToggleBold | Node::ToggleMath => unimplemented!(),
|
|
||||||
|
Node::ToggleItalics => self.italic = !self.italic,
|
||||||
|
Node::ToggleBold => self.bold = !self.bold,
|
||||||
|
|
||||||
|
Node::ToggleMath => unimplemented!(),
|
||||||
Node::Func(_) => unimplemented!(),
|
Node::Func(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,8 +185,8 @@ impl<'t> Engine<'t> {
|
|||||||
fn get_font_for(&self, character: char) -> TypeResult<(usize, Ref<Font>)> {
|
fn get_font_for(&self, character: char) -> TypeResult<(usize, Ref<Font>)> {
|
||||||
self.font_loader.get(FontQuery {
|
self.font_loader.get(FontQuery {
|
||||||
families: &self.ctx.style.font_families,
|
families: &self.ctx.style.font_families,
|
||||||
italic: false,
|
italic: self.italic,
|
||||||
bold: false,
|
bold: self.bold,
|
||||||
character,
|
character,
|
||||||
}).ok_or_else(|| TypesetError::MissingFont)
|
}).ok_or_else(|| TypesetError::MissingFont)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::io::{self, Cursor, Read, Seek, SeekFrom};
|
use std::io::{self, Cursor, Read, Seek, SeekFrom, BufReader};
|
||||||
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
||||||
use opentype::{Error as OpentypeError, OpenTypeReader, Outlines, TableRecord, Tag};
|
use opentype::{Error as OpentypeError, OpenTypeReader, Outlines, TableRecord, Tag};
|
||||||
use opentype::tables::{Header, Name, CharMap, MaximumProfile, HorizontalMetrics, Post, OS2};
|
use opentype::tables::{Header, Name, CharMap, MaximumProfile, HorizontalMetrics, Post, OS2};
|
||||||
@ -339,7 +339,7 @@ impl FontProvider for FileSystemFontProvider {
|
|||||||
let index = self.infos.iter().position(|i| i == info)?;
|
let index = self.infos.iter().position(|i| i == info)?;
|
||||||
let path = &self.paths[index];
|
let path = &self.paths[index];
|
||||||
let file = File::open(self.base.join(path)).ok()?;
|
let file = File::open(self.base.join(path)).ok()?;
|
||||||
Some(Box::new(file) as Box<FontData>)
|
Some(Box::new(BufReader::new(file)) as Box<FontData>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
23
src/lib.rs
23
src/lib.rs
@ -20,7 +20,7 @@
|
|||||||
//! use typeset::export::pdf::PdfExporter;
|
//! use typeset::export::pdf::PdfExporter;
|
||||||
//!
|
//!
|
||||||
//! // Simple example source code.
|
//! // Simple example source code.
|
||||||
//! let src = "Hello World from Typeset! 🌍";
|
//! let src = "Hello World from __Typeset__! 🌍";
|
||||||
//!
|
//!
|
||||||
//! // Create a compiler with a font provider that provides three fonts
|
//! // Create a compiler with a font provider that provides three fonts
|
||||||
//! // (the default sans-serif fonts and a fallback for the emoji).
|
//! // (the default sans-serif fonts and a fallback for the emoji).
|
||||||
@ -38,7 +38,7 @@
|
|||||||
//! # /*
|
//! # /*
|
||||||
//! let file = File::create("hello-typeset.pdf").unwrap();
|
//! let file = File::create("hello-typeset.pdf").unwrap();
|
||||||
//! # */
|
//! # */
|
||||||
//! # let file = File::create("../target/typeset-hello.pdf").unwrap();
|
//! # let file = File::create("../target/typeset-doc-hello.pdf").unwrap();
|
||||||
//! let exporter = PdfExporter::new();
|
//! let exporter = PdfExporter::new();
|
||||||
//! exporter.export(&document, file).unwrap();
|
//! exporter.export(&document, file).unwrap();
|
||||||
//! ```
|
//! ```
|
||||||
@ -167,16 +167,16 @@ mod test {
|
|||||||
let document = compiler.typeset(src).unwrap();
|
let document = compiler.typeset(src).unwrap();
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
let path = format!("../target/typeset-pdf-{}.pdf", name);
|
let path = format!("../target/typeset-unit-{}.pdf", name);
|
||||||
let file = BufWriter::new(File::create(path).unwrap());
|
let file = BufWriter::new(File::create(path).unwrap());
|
||||||
let exporter = PdfExporter::new();
|
let exporter = PdfExporter::new();
|
||||||
exporter.export(&document, file).unwrap();
|
exporter.export(&document, file).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn small() {
|
fn simple() {
|
||||||
test("parentheses", "Text with ) and ( or (enclosed) works.");
|
test("parentheses", "Text with ) and ( or (enclosed) works.");
|
||||||
test("multiline","
|
test("multiline-lorem","
|
||||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
|
||||||
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
|
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
|
||||||
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||||
@ -184,21 +184,22 @@ mod test {
|
|||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn unicode() {
|
|
||||||
test("unicode", "∑mbe∂∂ed font with Unicode!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn composite_glyph() {
|
fn composite_glyph() {
|
||||||
test("composite-glyph", "Composite character‼");
|
test("composite-glyph", "Composite character‼");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mixed_emoji() {
|
fn unicode() {
|
||||||
|
test("unicode", "∑mbe∂∂ed font with Unicode!");
|
||||||
test("mixed-emoji", "Hello World 🌍!")
|
test("mixed-emoji", "Hello World 🌍!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn styled() {
|
||||||
|
test("styled", "**Hello World**. That's __great__!");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn long_wikipedia() {
|
fn long_wikipedia() {
|
||||||
test("wikipedia", r#"
|
test("wikipedia", r#"
|
||||||
|
@ -249,7 +249,12 @@ impl<'s, T> Parser<'s, T> where T: Iterator<Item=Token<'s>> {
|
|||||||
PS::Body => match token {
|
PS::Body => match token {
|
||||||
// Whitespace
|
// Whitespace
|
||||||
Token::Space => self.append(Node::Space),
|
Token::Space => self.append(Node::Space),
|
||||||
Token::Newline => self.append(Node::Newline),
|
Token::Newline => {
|
||||||
|
self.append(Node::Newline);
|
||||||
|
if self.tokens.peek() != Some(&Token::Space) {
|
||||||
|
self.append(Node::Space);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Words
|
// Words
|
||||||
Token::Word(word) => self.append(Node::Word(word)),
|
Token::Word(word) => self.append(Node::Word(word)),
|
||||||
@ -382,6 +387,17 @@ mod token_tests {
|
|||||||
test("\n", vec![N]);
|
test("\n", vec![N]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This test looks if LF- and CRLF-style newlines get both identified correctly
|
||||||
|
#[test]
|
||||||
|
fn tokenize_whitespace_newlines() {
|
||||||
|
test(" \t", vec![S]);
|
||||||
|
test("First line\r\nSecond line\nThird line\n",
|
||||||
|
vec![W("First"), S, W("line"), N, W("Second"), S, W("line"), N,
|
||||||
|
W("Third"), S, W("line"), N]);
|
||||||
|
test("Hello \n ", vec![W("Hello"), S, N, S]);
|
||||||
|
test("Dense\nTimes", vec![W("Dense"), N, W("Times")]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests if escaping with backslash works as it should.
|
/// Tests if escaping with backslash works as it should.
|
||||||
#[test]
|
#[test]
|
||||||
fn tokenize_escape() {
|
fn tokenize_escape() {
|
||||||
@ -454,21 +470,12 @@ mod token_tests {
|
|||||||
vec![L, W("document"), R, L, W("Hello"), S, W("🌍"), W("!"), R]);
|
vec![L, W("document"), R, L, W("Hello"), S, W("🌍"), W("!"), R]);
|
||||||
test("[f]⺐.", vec![L, W("f"), R, W("⺐"), W(".")]);
|
test("[f]⺐.", vec![L, W("f"), R, W("⺐"), W(".")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test looks if LF- and CRLF-style newlines get both identified correctly.
|
|
||||||
#[test]
|
|
||||||
fn tokenize_whitespace_newlines() {
|
|
||||||
test(" \t", vec![S]);
|
|
||||||
test("First line\r\nSecond line\nThird line\n",
|
|
||||||
vec![W("First"), S, W("line"), N, W("Second"), S, W("line"), N,
|
|
||||||
W("Third"), S, W("line"), N]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod parse_tests {
|
mod parse_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use Node::{Space as S, Word as W, Func as F};
|
use Node::{Space as S, Word as W, Newline as N, Func as F};
|
||||||
|
|
||||||
/// Test if the source code parses into the syntax tree.
|
/// Test if the source code parses into the syntax tree.
|
||||||
fn test(src: &str, tree: SyntaxTree) {
|
fn test(src: &str, tree: SyntaxTree) {
|
||||||
@ -496,6 +503,15 @@ mod parse_tests {
|
|||||||
test("Hello World!", tree! { W("Hello"), S, W("World"), W("!")});
|
test("Hello World!", tree! { W("Hello"), S, W("World"), W("!")});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test whether newlines generate the correct whitespace.
|
||||||
|
#[test]
|
||||||
|
fn parse_newlines_whitespace() {
|
||||||
|
test("Hello \n World", tree! { W("Hello"), S, N, S, W("World") });
|
||||||
|
test("Hello\nWorld", tree! { W("Hello"), N, S, W("World") });
|
||||||
|
test("Hello\n World", tree! { W("Hello"), N, S, W("World") });
|
||||||
|
test("Hello \nWorld", tree! { W("Hello"), S, N, S, W("World") });
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse things dealing with functions.
|
/// Parse things dealing with functions.
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_functions() {
|
fn parse_functions() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user