Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Freemarker FO有序列表项标签罗马数字_Freemarker - Fatal编程技术网

Freemarker FO有序列表项标签罗马数字

Freemarker 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

我正在将两个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>
    
    
    ${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)}