FO订购的清单项目标签为罗马数字



我正在将两个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 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>
&#x2022;
</#if>
</fo:block>
</fo:list-item-label>
...
</fo:list-item>

从2.3.28起,FreeMarker中没有内置罗马数字格式(上次我检查时,Java中也没有(。也许应该有……但现在,你必须自己滚动(为它写一个TemplateMethodModelEx(。

就像前面提到的ddekany一样,您可以创建自己的方法。以下是如何做到这一点的示例:

Java代码

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));

这就是您在Freemark:中使用它的方式

${roman(true, 1234)}

最新更新