From fa387bb29cdc935b081ff56048f18aa4944ddaa8 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 4 Mar 2025 11:52:12 +0100 Subject: [PATCH] #410 fix frontmatter parsing --- CHANGELOG.md | 2 + .../cms/content/DefaultContentParser.java | 47 +++++------ .../cms/content/DefaultContentParserTest.java | 77 +++++++++++++++++++ 3 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 cms-content/src/test/java/com/condation/cms/content/DefaultContentParserTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f63369517..843db5b0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ see wiki for more information: [wiki](https://github.com/thmarx/cms/wiki) * **BUG** Missing template filter (date) added [#397](https://github.com/CondationCMS/cms-server/pull/397) * **FEATURE** Add variables to request context to share data in request scope [#403](https://github.com/CondationCMS/cms-server/pull/403) * **FEATURE** use request variables in expression context [#404](https://github.com/CondationCMS/cms-server/pull/404) +* **FEATURE** allow inline markdown rules in heading [#409](https://github.com/CondationCMS/cms-server/pull/409) +* **BUG** horizontal rule doesn't work as expected [#410](https://github.com/CondationCMS/cms-server/issues/410) ## 7.6.3 diff --git a/cms-content/src/main/java/com/condation/cms/content/DefaultContentParser.java b/cms-content/src/main/java/com/condation/cms/content/DefaultContentParser.java index 86c8112ff..068146c63 100644 --- a/cms-content/src/main/java/com/condation/cms/content/DefaultContentParser.java +++ b/cms-content/src/main/java/com/condation/cms/content/DefaultContentParser.java @@ -21,7 +21,6 @@ * . * #L% */ - import com.condation.cms.api.content.ContentParser; import com.condation.cms.api.db.cms.ReadOnlyFile; import com.google.common.base.Strings; @@ -38,15 +37,14 @@ * @author t.marx */ @Slf4j -public class DefaultContentParser implements ContentParser{ +public class DefaultContentParser implements ContentParser { - public DefaultContentParser() { } @Override public void clearCache() { - + } @Override @@ -55,18 +53,18 @@ public Content parse(final ReadOnlyFile contentFile) throws IOException { return new Content(readContent.content(), _parseMeta(readContent)); } - - private Map _parseMeta (ContentRecord content) { - if (Strings.isNullOrEmpty(content.meta().trim())) { - return Collections.emptyMap(); - } + + private Map _parseMeta(ContentRecord content) { + if (Strings.isNullOrEmpty(content.meta().trim())) { + return Collections.emptyMap(); + } try { return new Yaml().load(content.meta().trim()); } catch (Exception e) { log.error("error parsing yaml: " + content.meta(), e); throw new RuntimeException(e); } - } + } @Override public Map parseMeta(final ReadOnlyFile contentFile) throws IOException { @@ -81,23 +79,28 @@ private ContentRecord readContent(final ReadOnlyFile contentFile) throws IOExcep StringBuilder contentBuilder = new StringBuilder(); StringBuilder metaBuilder = new StringBuilder(); - AtomicBoolean inFrontMatter = new AtomicBoolean(true); - AtomicInteger counter = new AtomicInteger(0); - fileContent.stream().forEach((line) -> { - if (line.trim().equals("---")) { - counter.incrementAndGet(); - if (counter.get() == 2) { - inFrontMatter.set(false); + boolean inFrontMatter = false; + boolean frontMatterClosed = false; + + for (String line : fileContent) { + if (line.trim().equals("---") && !frontMatterClosed) { + if (!inFrontMatter) { + inFrontMatter = true; // Start Frontmatter + continue; + } else if (!frontMatterClosed) { + frontMatterClosed = true; // Ende Frontmatter + inFrontMatter = false; + continue; } - return; - } - if (inFrontMatter.get()) { + } + + if (inFrontMatter) { metaBuilder.append(line).append("\r\n"); } else { contentBuilder.append(line).append("\r\n"); } - }); - + } + return new ContentRecord(contentBuilder.toString(), metaBuilder.toString()); } } diff --git a/cms-content/src/test/java/com/condation/cms/content/DefaultContentParserTest.java b/cms-content/src/test/java/com/condation/cms/content/DefaultContentParserTest.java new file mode 100644 index 000000000..90154ad55 --- /dev/null +++ b/cms-content/src/test/java/com/condation/cms/content/DefaultContentParserTest.java @@ -0,0 +1,77 @@ +package com.condation.cms.content; + +/*- + * #%L + * cms-content + * %% + * Copyright (C) 2023 - 2025 CondationCMS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.condation.cms.api.content.ContentParser; +import com.condation.cms.api.db.cms.ReadOnlyFile; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * + * @author t.marx + */ +public class DefaultContentParserTest { + + ContentParser sut; + + @BeforeEach + private void setup () { + sut = new DefaultContentParser(); + } + + @Test + public void testSomeMethod() throws Exception { + + List lines = new ArrayList<>(); + lines.add("---"); + lines.add("title: The title"); + lines.add("---"); + lines.add("Here is the Content"); + lines.add("---"); + lines.add("With an hr"); + + var expectedMeta = Map.of("title", "The title"); + var expectedContent = "Here is the Content\r\n"; + expectedContent += "---\r\n"; + expectedContent += "With an hr\r\n"; + + var readOnlyFile = Mockito.mock(ReadOnlyFile.class); + Mockito.when(readOnlyFile.getAllLines()).thenReturn(lines); + + var content = sut.parse(readOnlyFile); + + Assertions.assertThat(content.meta()) + .isEqualTo(expectedMeta); + + Assertions.assertThat(content.content()) + .isEqualTo(expectedContent); + + } + +}