Skip to content

Commit 615fbac

Browse files
committed
Normalise to jats when input is plain text
1 parent 529c542 commit 615fbac

3 files changed

Lines changed: 127 additions & 17 deletions

File tree

thoth-api/src/graphql/tests.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,6 +2546,73 @@ query LinkedRelations($reviewId: Uuid!, $endorsementId: Uuid!) {
25462546
assert!(data["endorsement"]["authorInstitution"].is_null());
25472547
}
25482548

2549+
#[test]
2550+
fn graphql_markup_mutations_accept_plain_text_when_markup_is_jats_xml() {
2551+
let (_guard, pool) = test_db::setup_test_db();
2552+
let schema = create_schema();
2553+
let superuser = test_db::test_superuser("user-jats-xml-mutations");
2554+
let context = test_db::test_context_with_user(pool.clone(), superuser);
2555+
let seed = seed_data(&schema, &context);
2556+
2557+
let title = Title::from_id(pool.as_ref(), &seed.title_id).unwrap();
2558+
update_with_data_and_markup(
2559+
&schema,
2560+
&context,
2561+
"updateTitle",
2562+
"PatchTitle",
2563+
"titleId",
2564+
PatchTitle {
2565+
title_id: title.title_id,
2566+
work_id: title.work_id,
2567+
locale_code: title.locale_code,
2568+
full_title: "Foundations for Moral <italic>Relativism</italic> Second Expanded Edition"
2569+
.to_string(),
2570+
title: "Foundations for Moral <italic>Relativism</italic>".to_string(),
2571+
subtitle: Some("Second Expanded Edition".to_string()),
2572+
canonical: title.canonical,
2573+
},
2574+
MarkupFormat::JatsXml,
2575+
);
2576+
2577+
let stored_title = Title::from_id(pool.as_ref(), &seed.title_id).unwrap();
2578+
assert_eq!(
2579+
stored_title.full_title,
2580+
"Foundations for Moral <italic>Relativism</italic> Second Expanded Edition"
2581+
);
2582+
assert_eq!(
2583+
stored_title.title,
2584+
"Foundations for Moral <italic>Relativism</italic>"
2585+
);
2586+
assert_eq!(
2587+
stored_title.subtitle.as_deref(),
2588+
Some("Second Expanded Edition")
2589+
);
2590+
2591+
let abstract_item = Abstract::from_id(pool.as_ref(), &seed.abstract_short_id).unwrap();
2592+
update_with_data_and_markup(
2593+
&schema,
2594+
&context,
2595+
"updateAbstract",
2596+
"PatchAbstract",
2597+
"abstractId",
2598+
PatchAbstract {
2599+
abstract_id: abstract_item.abstract_id,
2600+
work_id: abstract_item.work_id,
2601+
content: "Plain abstract content updated".to_string(),
2602+
locale_code: abstract_item.locale_code,
2603+
abstract_type: abstract_item.abstract_type,
2604+
canonical: abstract_item.canonical,
2605+
},
2606+
MarkupFormat::JatsXml,
2607+
);
2608+
2609+
let stored_abstract = Abstract::from_id(pool.as_ref(), &seed.abstract_short_id).unwrap();
2610+
assert_eq!(
2611+
stored_abstract.content,
2612+
"<p>Plain abstract content updated</p>"
2613+
);
2614+
}
2615+
25492616
#[test]
25502617
fn graphql_mutations_cover_all() {
25512618
let (_guard, pool) = test_db::setup_test_db();

thoth-api/src/markup/mod.rs

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,32 @@ pub fn convert_to_jats(
7474
format: MarkupFormat,
7575
conversion_limit: ConversionLimit,
7676
) -> ThothResult<String> {
77+
if format == MarkupFormat::JatsXml {
78+
let content_looks_like_jats = content.contains('<') && content.contains("</");
79+
let ast = if content_looks_like_jats {
80+
jats_to_ast(&content)
81+
} else {
82+
plain_text_to_ast(&content)
83+
};
84+
85+
let processed_ast = if conversion_limit == ConversionLimit::Title {
86+
strip_structural_elements_from_ast_for_conversion(&ast)
87+
} else {
88+
ast
89+
};
90+
91+
validate_ast_content(&processed_ast, conversion_limit)?;
92+
93+
return Ok(
94+
if content_looks_like_jats || conversion_limit == ConversionLimit::Title {
95+
ast_to_jats(&processed_ast)
96+
} else {
97+
plain_text_ast_to_jats(&processed_ast)
98+
},
99+
);
100+
}
101+
77102
validate_format(&content, &format)?;
78-
let mut output = content.clone();
79103

80104
match format {
81105
MarkupFormat::Html => {
@@ -90,7 +114,7 @@ pub fn convert_to_jats(
90114
};
91115

92116
validate_ast_content(&processed_ast, conversion_limit)?;
93-
output = ast_to_jats(&processed_ast);
117+
Ok(ast_to_jats(&processed_ast))
94118
}
95119

96120
MarkupFormat::Markdown => {
@@ -105,7 +129,7 @@ pub fn convert_to_jats(
105129
};
106130

107131
validate_ast_content(&processed_ast, conversion_limit)?;
108-
output = ast_to_jats(&processed_ast);
132+
Ok(ast_to_jats(&processed_ast))
109133
}
110134

111135
MarkupFormat::PlainText => {
@@ -120,18 +144,16 @@ pub fn convert_to_jats(
120144
};
121145

122146
validate_ast_content(&processed_ast, conversion_limit)?;
123-
output = if conversion_limit == ConversionLimit::Title {
147+
Ok(if conversion_limit == ConversionLimit::Title {
124148
// Title JATS should remain inline (no paragraph wrapper)
125149
ast_to_jats(&processed_ast)
126150
} else {
127151
plain_text_ast_to_jats(&processed_ast)
128-
};
152+
})
129153
}
130154

131-
MarkupFormat::JatsXml => {}
155+
MarkupFormat::JatsXml => unreachable!("handled above"),
132156
}
133-
134-
Ok(output)
135157
}
136158

137159
/// Convert from JATS XML to specified format using a specific tag name
@@ -347,6 +369,30 @@ mod tests {
347369
.unwrap();
348370
assert_eq!(output, "Just plain text.");
349371
}
372+
373+
#[test]
374+
fn test_jatsxml_plain_text_title_is_accepted() {
375+
let input = "Second Expanded Edition";
376+
let output = convert_to_jats(
377+
input.to_string(),
378+
MarkupFormat::JatsXml,
379+
ConversionLimit::Title,
380+
)
381+
.unwrap();
382+
assert_eq!(output, input);
383+
}
384+
385+
#[test]
386+
fn test_jatsxml_plain_text_abstract_is_wrapped() {
387+
let input = "Plain abstract content.";
388+
let output = convert_to_jats(
389+
input.to_string(),
390+
MarkupFormat::JatsXml,
391+
ConversionLimit::Abstract,
392+
)
393+
.unwrap();
394+
assert_eq!(output, "<p>Plain abstract content.</p>");
395+
}
350396
// --- convert_to_jats tests end ---
351397

352398
// --- convert_from_jats tests start ---

thoth-api/src/model/title/tests.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ mod conversions {
2727
#[test]
2828
fn convert_title_to_jats_updates_fields() {
2929
let mut title = Title {
30-
title: "<title>My Title</title>".to_string(),
31-
subtitle: Some("<subtitle>Sub</subtitle>".to_string()),
32-
full_title: "<title>My Title: Sub</title>".to_string(),
30+
title: "My <italic>Title</italic>".to_string(),
31+
subtitle: Some("Sub".to_string()),
32+
full_title: "My <italic>Title</italic>: Sub".to_string(),
3333
locale_code: LocaleCode::En,
3434
canonical: false,
3535
..Default::default()
@@ -38,12 +38,9 @@ mod conversions {
3838
convert_title_to_jats(&mut title, MarkupFormat::JatsXml)
3939
.expect("Failed to convert title to JATS");
4040

41-
assert_eq!(title.title(), "<title>My Title</title>");
42-
assert_eq!(
43-
TitleProperties::subtitle(&title),
44-
Some("<subtitle>Sub</subtitle>")
45-
);
46-
assert_eq!(title.full_title(), "<title>My Title: Sub</title>");
41+
assert_eq!(title.title(), "My <italic>Title</italic>");
42+
assert_eq!(TitleProperties::subtitle(&title), Some("Sub"));
43+
assert_eq!(title.full_title(), "My <italic>Title</italic>: Sub");
4744
}
4845
}
4946

0 commit comments

Comments
 (0)