Skip to content

Commit cb07670

Browse files
committed
Merge branch 'release/v1.0.1'
2 parents 59f3dda + 8bcfcd8 commit cb07670

10 files changed

Lines changed: 102 additions & 45 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [[1.0.0]](https://github.com/thoth-pub/thoth/releases/tag/v1.0.0) - 2026-04-01
10+
### Fixed
11+
- Return raw JATS XML rather than attempting to validate it
12+
913
## [[1.0.0]](https://github.com/thoth-pub/thoth/releases/tag/v1.0.0) - 2026-04-01
1014
### Changed
1115
- [736](https://github.com/thoth-pub/thoth/pull/736) - Remove `Funding.jurisdiction` and `Language.mainLanguage`, and add `Issue.issueNumber`

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -15,10 +15,10 @@ maintenance = { status = "actively-developed" }
1515
members = ["thoth-api", "thoth-api-server", "thoth-client", "thoth-errors", "thoth-export-server"]
1616

1717
[dependencies]
18-
thoth-api = { version = "=1.0.0", path = "thoth-api", features = ["backend"] }
19-
thoth-api-server = { version = "=1.0.0", path = "thoth-api-server" }
20-
thoth-errors = { version = "=1.0.0", path = "thoth-errors" }
21-
thoth-export-server = { version = "=1.0.0", path = "thoth-export-server" }
18+
thoth-api = { version = "=1.0.1", path = "thoth-api", features = ["backend"] }
19+
thoth-api-server = { version = "=1.0.1", path = "thoth-api-server" }
20+
thoth-errors = { version = "=1.0.1", path = "thoth-errors" }
21+
thoth-export-server = { version = "=1.0.1", path = "thoth-export-server" }
2222
base64 = "0.22.1"
2323
clap = { version = "4.5.32", features = ["cargo", "env"] }
2424
dialoguer = { version = "0.11.0", features = ["password"] }

thoth-api-server/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth-api-server"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -9,8 +9,8 @@ repository = "https://github.com/thoth-pub/thoth"
99
readme = "README.md"
1010

1111
[dependencies]
12-
thoth-api = { version = "=1.0.0", path = "../thoth-api", features = ["backend"] }
13-
thoth-errors = { version = "=1.0.0", path = "../thoth-errors" }
12+
thoth-api = { version = "=1.0.1", path = "../thoth-api", features = ["backend"] }
13+
thoth-errors = { version = "=1.0.1", path = "../thoth-errors" }
1414
actix-web = "4.10"
1515
actix-cors = "0.7.1"
1616
actix-http = "3.10.0"

thoth-api/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth-api"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -32,7 +32,7 @@ backend = [
3232
]
3333

3434
[dependencies]
35-
thoth-errors = { version = "=1.0.0", path = "../thoth-errors" }
35+
thoth-errors = { version = "=1.0.1", path = "../thoth-errors" }
3636
actix-web = { version = "4.10", optional = true }
3737
argon2rs = { version = "0.2.5", optional = true }
3838
isbn = "0.6.0"

thoth-api/src/markup/ast.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -546,19 +546,19 @@ pub fn jats_to_ast(jats: &str) -> Node {
546546
}
547547

548548
match tag_name {
549-
"article" | "body" | "sec" | "div" => Node::Document(children),
549+
"html" | "article" | "body" | "sec" | "div" => Node::Document(children),
550550
"p" => Node::Paragraph(children),
551551
"break" | "br" => Node::Break,
552-
"bold" => Node::Bold(children),
553-
"italic" => Node::Italic(children),
554-
"underline" => Node::Underline(children),
555-
"strike" => Node::Strikethrough(children),
556-
"monospace" => Node::Code(children),
552+
"bold" | "strong" | "b" => Node::Bold(children),
553+
"italic" | "em" | "i" => Node::Italic(children),
554+
"underline" | "u" => Node::Underline(children),
555+
"strike" | "s" | "del" | "strikethrough" => Node::Strikethrough(children),
556+
"monospace" | "code" => Node::Code(children),
557557
"sup" => Node::Superscript(children),
558558
"sub" => Node::Subscript(children),
559-
"sc" => Node::SmallCaps(children),
560-
"list" => Node::List(children),
561-
"list-item" => Node::ListItem(children),
559+
"sc" | "text" => Node::SmallCaps(children),
560+
"list" | "ul" | "ol" => Node::List(children),
561+
"list-item" | "li" => Node::ListItem(children),
562562
"span" => {
563563
if element
564564
.value()

thoth-api/src/markup/mod.rs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,34 @@ fn looks_like_markup(content: &str) -> bool {
5555

5656
fn validate_jats_subset(content: &str) -> ThothResult<()> {
5757
let allowed_tags = [
58+
"html",
5859
"p",
5960
"break",
61+
"br",
6062
"bold",
63+
"strong",
64+
"b",
6165
"italic",
66+
"em",
67+
"i",
6268
"underline",
69+
"u",
6370
"strike",
71+
"s",
72+
"del",
73+
"strikethrough",
6474
"monospace",
75+
"code",
6576
"sup",
6677
"sub",
6778
"sc",
79+
"text",
6880
"list",
81+
"ul",
82+
"ol",
6983
"list-item",
84+
"li",
85+
"a",
7086
"ext-link",
7187
"inline-formula",
7288
"tex-math",
@@ -250,6 +266,10 @@ pub fn convert_from_jats(
250266
format: MarkupFormat,
251267
conversion_limit: ConversionLimit,
252268
) -> ThothResult<String> {
269+
if format == MarkupFormat::JatsXml {
270+
return Ok(jats_xml.to_string());
271+
}
272+
253273
// Allow plain-text content that was stored without JATS markup for titles.
254274
if !looks_like_markup(jats_xml) {
255275
let ast = plain_text_to_ast(jats_xml);
@@ -273,10 +293,7 @@ pub fn convert_from_jats(
273293
});
274294
}
275295

276-
validate_format(jats_xml, &MarkupFormat::JatsXml)?;
277-
validate_jats_subset(jats_xml)?;
278-
279-
// Parse JATS to AST first for better handling
296+
// Read paths need to tolerate legacy stored markup and normalize it on the fly.
280297
let ast = jats_to_ast(jats_xml);
281298

282299
// For title conversion, strip structural elements before validation
@@ -286,9 +303,6 @@ pub fn convert_from_jats(
286303
ast
287304
};
288305

289-
// Validate the AST content based on conversion limit
290-
validate_ast_content(&processed_ast, conversion_limit)?;
291-
292306
let output = match format {
293307
MarkupFormat::Html => {
294308
// Use the dedicated AST to HTML converter
@@ -305,10 +319,7 @@ pub fn convert_from_jats(
305319
ast_to_plain_text(&processed_ast)
306320
}
307321

308-
MarkupFormat::JatsXml => {
309-
// Return the AST converted back to JATS (should be identical)
310-
jats_xml.to_string()
311-
}
322+
MarkupFormat::JatsXml => unreachable!("handled above"),
312323
};
313324

314325
Ok(output)
@@ -498,6 +509,21 @@ mod tests {
498509
assert!(output.contains("<break/>"));
499510
}
500511

512+
#[test]
513+
fn test_jatsxml_legacy_inline_html_is_normalized_on_write() {
514+
let input = r#"<p><i>Italic</i> <u>Underline</u> <a href="https://example.org">Link</a></p>"#;
515+
let output = convert_to_jats(
516+
input.to_string(),
517+
MarkupFormat::JatsXml,
518+
ConversionLimit::Abstract,
519+
)
520+
.unwrap();
521+
522+
assert!(output.contains("<italic>Italic</italic>"));
523+
assert!(output.contains("<underline>Underline</underline>"));
524+
assert!(output.contains(r#"<ext-link xlink:href="https://example.org">Link</ext-link>"#));
525+
}
526+
501527
#[test]
502528
fn test_html_break_formula_email_and_uri_conversion() {
503529
let input = r#"<p>Line<br/><span class="inline-formula">E=mc^2</span> <a href="mailto:user@example.org">user@example.org</a> <a href="https://example.org">https://example.org</a></p>"#;
@@ -658,6 +684,33 @@ mod tests {
658684
assert_eq!(input, output);
659685
}
660686

687+
#[test]
688+
fn test_convert_from_jats_jatsxml_passes_through_legacy_markup() {
689+
let input = r#"<p><i>Italic</i> <u>Underline</u> <a href="https://example.org">Link</a></p>"#;
690+
let output =
691+
convert_from_jats(input, MarkupFormat::JatsXml, ConversionLimit::Abstract).unwrap();
692+
assert_eq!(input, output);
693+
}
694+
695+
#[test]
696+
fn test_convert_from_jats_html_accepts_legacy_inline_html_tags() {
697+
let input = r#"<p><i>Italic</i> <u>Underline</u> <a href="https://example.org">Link</a></p>"#;
698+
let output =
699+
convert_from_jats(input, MarkupFormat::Html, ConversionLimit::Abstract).unwrap();
700+
701+
assert!(output.contains("<em>Italic</em>"));
702+
assert!(output.contains("<u>Underline</u>"));
703+
assert!(output.contains(r#"<a href="https://example.org">Link</a>"#));
704+
}
705+
706+
#[test]
707+
fn test_convert_from_jats_html_title_flattens_multiple_top_level_nodes() {
708+
let input = r#"<p>Legacy Title</p><i> Supplement</i>"#;
709+
let output = convert_from_jats(input, MarkupFormat::Html, ConversionLimit::Title).unwrap();
710+
711+
assert_eq!(output, "Legacy Title<em> Supplement</em>");
712+
}
713+
661714
#[test]
662715
fn test_convert_from_jats_markdown_formula_email_uri_and_break() {
663716
let input = "<p>Line<break/><inline-formula><tex-math>E=mc^2</tex-math></inline-formula> <email>user@example.org</email> <uri>https://example.org</uri></p>";

thoth-client/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth-client"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -10,8 +10,8 @@ readme = "README.md"
1010
build = "build.rs"
1111

1212
[dependencies]
13-
thoth-api = {version = "=1.0.0", path = "../thoth-api" }
14-
thoth-errors = {version = "=1.0.0", path = "../thoth-errors" }
13+
thoth-api = {version = "=1.0.1", path = "../thoth-api" }
14+
thoth-errors = {version = "=1.0.1", path = "../thoth-errors" }
1515
graphql_client = "0.14.0"
1616
chrono = { version = "0.4.40", features = ["serde"] }
1717
reqwest = { version = "0.12", features = ["json"] }
@@ -22,4 +22,4 @@ serde_json = "1.0"
2222
uuid = { version = "1.16.0", features = ["serde"] }
2323

2424
[build-dependencies]
25-
thoth-api = { version = "=1.0.0", path = "../thoth-api", features = ["backend"] }
25+
thoth-api = { version = "=1.0.1", path = "../thoth-api", features = ["backend"] }

thoth-errors/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth-errors"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"

thoth-export-server/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thoth-export-server"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
authors = ["Javier Arias <javi@thoth.pub>", "Ross Higman <ross@thoth.pub>"]
55
edition = "2021"
66
license = "Apache-2.0"
@@ -10,9 +10,9 @@ readme = "README.md"
1010
build = "build.rs"
1111

1212
[dependencies]
13-
thoth-api = { version = "=1.0.0", path = "../thoth-api" }
14-
thoth-errors = { version = "=1.0.0", path = "../thoth-errors" }
15-
thoth-client = { version = "=1.0.0", path = "../thoth-client" }
13+
thoth-api = { version = "=1.0.1", path = "../thoth-api" }
14+
thoth-errors = { version = "=1.0.1", path = "../thoth-errors" }
15+
thoth-client = { version = "=1.0.1", path = "../thoth-client" }
1616
actix-web = "4.10"
1717
actix-cors = "0.7.1"
1818
cc_license = "0.1.0"

0 commit comments

Comments
 (0)