Freemarker FO有序列表项标签罗马数字
我正在将两个XSLT文件转换为freemarker。一个是HTML,另一个是FO。我需要能够根据变量typeordered生成列表项标签,该变量可以是值1、a、a、I、I(在html有序列表类型中使用)之一 原始html.xslFreemarker FO有序列表项标签罗马数字,freemarker,Freemarker,我正在将两个XSLT文件转换为freemarker。一个是HTML,另一个是FO。我需要能够根据变量typeordered生成列表项标签,该变量可以是值1、a、a、I、I(在html有序列表类型中使用)之一 原始html.xsl <ol type="{typeordered}"> <li>...</li> </ol> 原始fo.xsl <fo:list-item> <fo:list-item-label e
<ol type="{typeordered}">
<li>...</li>
</ol>
原始fo.xsl
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block><xsl:number format="{typeordered}" /></fo:block>
</fo:list-item-label>
...
</fo:list-item>
...
FO自由标记版本。可以使用小写/大写字母,但如何使用罗马数字?看起来太复杂了
<#macro listItemM listItem listElement n>
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<#if listElement.type == "ordered">
<#if listElement.typeordered??>
<#if listElement.typeordered == "a">
${n?lower_abc}
<#elseif listElement.typeordered == "A">
${n?upper_abc}
<#else>
${n}
</#if>
<#else>
${n}
</#if>.
<#else>
•
</#if>
</fo:block>
</fo:list-item-label>
...
</fo:list-item>
${n?下_abc}
${n?上_abc}
${n}
${n}
.
•;
...
从2.3.28开始,FreeMarker中没有内置罗马数字格式(上次我检查时,Java中也没有)。也许应该有。。。但是现在,你必须自己动手(为它写一个TemplateMethodModelEx
。就像前面提到的那样,你可以创建自己的方法。下面是一个示例,说明了如何做到这一点:
Java代码
标记为答案,因为它包含完整代码sample@gil.fernandes考虑把这个贡献给Apache Frimalk。(当然,它还需要更多的工作,比如处理一些边缘案例、测试、Apache的ICLA等等)@ddekany我很荣幸您提出了这样的要求。好的,我会在接下来的几天里花一些时间来做这件事。请注意:我还没有在Apache上提交ICLA,但我会这样做。@gil.fernandes很棒,请参阅以获取指导。(这更像是当有人花时间做出贡献时我们感到荣幸。)@ddekany这是我完成的类,由
${listItemLabel(listElement.typeordered,n)}
import freemarker.template.*;
import java.util.List;
import java.util.TreeMap;
public class RomanNumerals implements TemplateMethodModelEx {
private final static TreeMap<Integer, String> map = new TreeMap<>();
static {
map.put(1000, "M");
map.put(900, "CM");
map.put(500, "D");
map.put(400, "CD");
map.put(100, "C");
map.put(90, "XC");
map.put(50, "L");
map.put(40, "XL");
map.put(10, "X");
map.put(9, "IX");
map.put(5, "V");
map.put(4, "IV");
map.put(1, "I");
}
// Copied from Stackoverflow https://stackoverflow.com/a/19759564/2735286
private static String toRoman(int number) {
int l = map.floorKey(number);
if (number == l) {
return map.get(number);
}
return map.get(l) + toRoman(number - l);
}
@Override
public Object exec(List arguments) throws TemplateModelException {
final boolean upperCase = ((TemplateBooleanModel) arguments.get(0)).getAsBoolean();
final Integer number = ((SimpleNumber) arguments.get(1)).getAsNumber().intValue();
String roman = toRoman(number);
return new SimpleScalar(upperCase ? roman : roman.toLowerCase());
}
}
HashMap<String, Object> dataModel = new HashMap<>();
dataModel.put("date", new Date());
dataModel.put("roman", new RomanNumerals());
testTemplate.process(dataModel, new PrintWriter(System.out));
${roman(true, 1234)}