Universal Wiki Converter
-- set version to 3.13.1_SNAPSHOT
-- improved trac link handling: (double brackets links, better alias handling, improved escape linking, added link handling to work with new default hierarchy FilenameHierarchy)
git-svn-id: https://studio.plugins.atlassian.com/svn/UWC/devel@165785 2c54a935-e501-0410-bc05-97a93f6bca70
diff --git a/conf/converter.trac.properties b/conf/converter.trac.properties
index 6d4198c..c97e3b5 100644
--- a/conf/converter.trac.properties
+++ b/conf/converter.trac.properties
@@ -2,14 +2,21 @@
#Trac.0000-duplicate_lines.java-regex=\r\n\r\n{replace-with}NEWLINE
# Page Hierarchy
+## If your trac-admin dump creates a flat directory of pages
+## in which the hierarchy is maintained as url encoded filenames, then
+## use the FilenameHierarchy hierarchy-builder (default)
+## If your trac-admin dump creates a system hierarchy of files that matches
+## your page hierarchy, use the FilepathHierarchy hierarchy-builder. Do also
+## comment 1210 converter
Trac.0001.switch.hierarchy-builder=UseBuilder
-Trac.0002.classname.hierarchy-builder=com.atlassian.uwc.hierarchies.FilepathHierarchy
+Trac.0002.classname.hierarchy-builder=com.atlassian.uwc.hierarchies.FilenameHierarchy
+#Trac.0002.classname.hierarchy-builder=com.atlassian.uwc.hierarchies.FilepathHierarchy
#Trac.0003.filepath-hierarchy-ignorable-ancestors.property=/SET/THIS/To/the/location/of/your/pages
-Trac.0004.filepath-hierarchy-ext.property=
+#Trac.0004.filepath-hierarchy-ext.property=
# Preformatted text and wiki names
Trac.0050-preformatted.java-regex-tokenizer=(?ms)^\{{3}(.*?)^\}{3}{replace-multiline-with}{noformat}$1{noformat}
-Trac.0015-escaped_wikiname.java-regex-tokenizer= !([A-Z][a-z/]+[A-Z][a-z][\w/]+){replace-with} $1
+Trac.0015-escaped_wikiname.java-regex-tokenizer=(?<=^|\s)!([A-Z][a-z/]+[A-Z][a-z][\w/]+){replace-with}$1
# Escape characters that have a special meaning in Confluence
Trac.0060-escape_exclamation_marks.java-regex=!{replace-with}\\!
@@ -49,8 +56,10 @@
# Macros: Images, line breaks and generic
Trac.0600-macro_image_on_other_page.java-regex=\[\[Image\(wiki:([^:]+):([^\)]+)\)\]\]{replace-with}[[Image($1^$2)]]
Trac.0601-macro_image_attachment.java-regex=\[\[Image\(([^\)]+)\)\]\]{replace-with}!$1!
-Trac.0650-macro_br.java-regex=\[\[BR\]\]{replace-with}NEWLINE
-Trac.0699-macros.java-regex=\[{2}([^\]]+)\]{2}{replace-with}{$1}
+Trac.0650-macro_br.java-regex=\[\[BR\]\] ?{replace-with}NEWLINE
+Trac.0660-doublebracket-links.java-regex=\[{2}([^\]]+)\]{2}{replace-with}[$1]
+## This macros converter won't get called with 0660 enabled, so I've commented it for now.
+#Trac.0699-macros.java-regex=\[{2}([^\]]+)\]{2}{replace-with}{$1}
# Tables - copied from the MoinMoin converter
# BUG: || gets replaced in mormal text
@@ -70,10 +79,16 @@
Trac.1200-wikilink_prefix.java-regex=\[wiki:{replace-with}[
Trac.1201-wikilink_with_quotes.java-regex-tokenizer=\[\"([^\"]+)\"\]{replace-with}[$1]
Trac.1202-attachment_link.java-regex-tokenizer=\[attachment:{replace-with}[^
-Trac.1203-link_with_title.java-regex=\[([^ \]]+) ([^\]]+)\]{replace-with}[$2|$1]
+Trac.1203-link_with_title_pipe.java-regex-tokenizer=\[([^|\]]+)\|([^\]]+)\]{replace-with}[$2|$1]
+Trac.1204-link_with_title_space.java-regex=\[([^ \]]+) ([^\]]+)\]{replace-with}[$2|$1]
## For any tokenizer regex above, strip out tokens
Trac.2000-detokenize.class=com.atlassian.uwc.converters.DetokenizerConverter
+## Remove everything but leaf node part of link from link target. Works with
+## FilenameHierarchy. If you are not using the FilenameHierarchy, comment this
+## converter.
+Trac.2100-hierarchylink.class=com.atlassian.uwc.converters.trac.FilenameHierarchyLinkConverter
+
# Attachments
Trac.3000-attachments.class=com.atlassian.uwc.converters.trac.AttachmentConverter
diff --git a/sampleData/trac/SampleTrac-ExpectedBase.txt b/sampleData/trac/SampleTrac-ExpectedBase.txt
index 2440026..148051c 100644
--- a/sampleData/trac/SampleTrac-ExpectedBase.txt
+++ b/sampleData/trac/SampleTrac-ExpectedBase.txt
@@ -7,7 +7,7 @@
The second paragraph has some links: First we have internal wiki links like [TracGuide], [TracWiki] and to an [^Attached_File.pdf]. Links can be given a more descriptive title by writing the link followed by a space and a title and all this inside square brackets, like in [Trac Overview|TracOverview]. Links can be avoided by EscapingWikiNames.
-Of course, there can also be external links. URLs like http://www.google.com/search?q=Confluence are automatically linked but they can also be put inside square brackets: [http://www.google.de/search?hl=de&q=Confluence+Trac+importer&btnG=Suche&meta=], even with titles like [Google search for "trac export"|http://www.google.de/search?hl=de&q=trac+export&btnG=Suche&meta=]. We add some [relative links|#Relativelinks] and [links to|MainPage-SubWikiPage] [WikiPage-SubPages] just for fun.
+Of course, there can also be external links. URLs like http://www.google.com/search?q=Confluence are automatically linked but they can also be put inside square brackets: [http://www.google.de/search?hl=de&q=Confluence+Trac+importer&btnG=Suche&meta=], even with titles like [Google search for "trac export"|http://www.google.de/search?hl=de&q=trac+export&btnG=Suche&meta=]. We add some [relative links|#Relativelinks] and [links to|SubWikiPage] [SubPages] just for fun.
bq. This text is a quote from someone else, rendered as blockquote.
diff --git a/sampleData/trac/SampleTrac-ExpectedLinks.txt b/sampleData/trac/SampleTrac-ExpectedLinks.txt
new file mode 100644
index 0000000..305d34e
--- /dev/null
+++ b/sampleData/trac/SampleTrac-ExpectedLinks.txt
@@ -0,0 +1,33 @@
+
+internal wiki links
+[TracGuide]
+[TracWiki]
+[Somepage]
+[Somepage]
+
+attachment links
+[^Attached_File.pdf].
+
+links with aliases
+[Trac Overview|TracOverview]
+[Trac Guide with some German umlauts: ä ö ü|TracGuide].
+[This is another link to ticket number one|ticket].
+[the sandbox|SandBox]
+
+anchors
+[relative links|#Relativelinks]
+[relative links|#Relativelinks]
+
+escape links
+EscapingWikiNames.
+
+hierarchy
+[SubWikiPage]
+[SubWikiPage]
+[alias|SubWikiPage]
+[see next sibling|Sibling]
+[see next sibling|Sibling]
+
+breaks
+(included here because very much like link syntax)
+
diff --git a/sampleData/trac/SampleTrac-InputLinks.txt b/sampleData/trac/SampleTrac-InputLinks.txt
new file mode 100644
index 0000000..447bf9c
--- /dev/null
+++ b/sampleData/trac/SampleTrac-InputLinks.txt
@@ -0,0 +1,32 @@
+
+internal wiki links
+[wiki:TracGuide]
+["TracWiki"]
+[Somepage]
+[[Somepage]]
+
+attachment links
+[attachment:Attached_File.pdf].
+
+links with aliases
+[TracOverview Trac Overview]
+[wiki:TracGuide Trac Guide with some German umlauts: ä ö ü].
+[[ticket|This is another link to ticket number one]].
+[[SandBox|the sandbox]]
+
+anchors
+[#Relativelinks relative links]
+[[#Relativelinks|relative links]]
+
+escape links
+!EscapingWikiNames.
+
+hierarchy
+[WikiPage/SubWikiPage]
+[wiki:WikiPage/SubWikiPage]
+[wiki:WikiPage/SubWikiPage alias]
+[../Sibling see next sibling]
+[[../Sibling|see next sibling]]
+
+breaks [[BR]] (included here because very much like link syntax)
+
diff --git a/sampleData/trac/testall.sh b/sampleData/trac/testall.sh
index 00450b2..7f300cb 100755
--- a/sampleData/trac/testall.sh
+++ b/sampleData/trac/testall.sh
@@ -6,3 +6,6 @@
echo "Stack"
./compare.sh Stack
+echo "Links"
+./compare.sh Links
+
diff --git a/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverter.java b/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverter.java
new file mode 100644
index 0000000..421ad93
--- /dev/null
+++ b/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverter.java
@@ -0,0 +1,55 @@
+package com.atlassian.uwc.converters.trac;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.atlassian.uwc.converters.BaseConverter;
+import com.atlassian.uwc.converters.tikiwiki.RegexUtil;
+import com.atlassian.uwc.ui.Page;
+
+public class FilenameHierarchyLinkConverter extends BaseConverter {
+
+ @Override
+ public void convert(Page page) {
+ String input = page.getOriginalText();
+ String converted = convertLink(input);
+ page.setConvertedText(converted);
+ }
+
+ Pattern link = Pattern.compile("\\[([^\\]]+)\\]");
+ protected String convertLink(String input) {
+ Matcher linkFinder = link.matcher(input);
+ StringBuffer sb = new StringBuffer();
+ boolean found = false;
+ while (linkFinder.find()) {
+ found = true;
+ String link = linkFinder.group(1);
+ String alias = "";
+ if (link.contains("|")) {
+ String[] parts = link.split("\\|");
+ alias = parts[0];
+ link = parts[1];
+ }
+ if (link.startsWith("#")) continue; //anchor, skip
+ if (link.startsWith("^")) continue; //attachment, skip
+ if (!link.contains("/")) continue; //link will be fine with no changes
+ if (link.startsWith("http") ||
+ link.startsWith("mailto:") ||
+ link.startsWith("file:")) continue; //external link: skip
+
+
+ String[] nodes = link.split("\\/");
+ link = nodes[nodes.length-1];
+ if (!"".equals(alias)) alias += "|";
+ String replacement = "[" + alias + link + "]";
+ replacement = RegexUtil.handleEscapesInReplacement(replacement);
+ linkFinder.appendReplacement(sb, replacement);
+ }
+ if (found) {
+ linkFinder.appendTail(sb);
+ return sb.toString();
+ }
+ return input;
+ }
+
+}
diff --git a/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverterTest.java b/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverterTest.java
new file mode 100644
index 0000000..0b3c67e
--- /dev/null
+++ b/src/com/atlassian/uwc/converters/trac/FilenameHierarchyLinkConverterTest.java
@@ -0,0 +1,77 @@
+package com.atlassian.uwc.converters.trac;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+//at this stage we're done alot of link handling already, so this is really confluence link handling
+public class FilenameHierarchyLinkConverterTest extends TestCase {
+
+ FilenameHierarchyLinkConverter tester = null;
+ Logger log = Logger.getLogger(this.getClass());
+ protected void setUp() throws Exception {
+ super.setUp();
+ tester = new FilenameHierarchyLinkConverter();
+ PropertyConfigurator.configure("log4j.properties");
+ }
+
+ public void testConvertLinks_simple() {
+ String input, expected, actual;
+ input = "[WikiPage/SubWikiPage]";
+ expected = "[SubWikiPage]";
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+ public void testConvertLinks_alias() {
+ String input, expected, actual;
+ input = "[alias|WikiPage/SubWikiPage]";
+ expected = "[alias|SubWikiPage]";
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+ public void testConvertLinks_sibling() {
+ String input, expected, actual;
+ input = "[../Sibling]\n" +
+ "[alias|../Sibling]";
+ expected = "[Sibling]\n" +
+ "[alias|Sibling]";
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+ public void testConvertLinks_notattachment() {
+ String input, expected, actual;
+ input = "[alias/with dangerous chars|^file/wouldthisevenhappen.pdf]";
+ expected = input;
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+ public void testConvertLinks_notanchor() {
+ String input, expected, actual;
+ input = "[alias/foobar|#foo/bar]";
+ expected = input;
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+
+ public void testConvertLinks_notexternal() {
+ String input, expected, actual;
+ input = "[alias/foobar|http://lalala.com]";
+ expected = input;
+ actual = tester.convertLink(input);
+ assertNotNull(actual);
+ assertEquals(expected, actual);
+ }
+
+
+}
diff --git a/src/com/atlassian/uwc/ui/UWCForm3.java b/src/com/atlassian/uwc/ui/UWCForm3.java
index cfaed61..259a570 100644
--- a/src/com/atlassian/uwc/ui/UWCForm3.java
+++ b/src/com/atlassian/uwc/ui/UWCForm3.java
@@ -92,7 +92,7 @@
private static final String LOGIN_TOOLTIP = "This is the username of an account on the Confluence server with write privileges to the space where you\'re adding content.";
private static final String ADDRESS_TOOLTIP = "This is the url to Confluence. Example: 'localhost:8080'";
private static final String VERSION_INDICATOR = "";
- public static final String VERSION_NUMBER = "3.13.0";
+ public static final String VERSION_NUMBER = "3.13.1_Snapshot";
private static final Dimension TABBEDPANE_SIZE = new Dimension(420, 475);
public static final String APP_NAME = "Universal Wiki Converter";
private static final int BASIC_RIGHT_MARGIN = 35;