跳转到内容

User:Blove maple/CatnavGraph/source

维基百科,自由的百科全书
package blove.catbot.catnavGraph;

/**
 * 生成CatnavGraph模板代码。<br>
 * 模板参数: <li>
 * "siblings":在同一级别的最大节点个数 <li>
 * "item"+rowIndex+columnIndex:对应行列项目的分类名;“-”表示连接左右的中央横线 <li>
 * "postline"+rowIndex+columnIndex:项目后面的指示线类型<br>
 * 指示线类型:8上中、4下中、2左中、1右中。
 * 
 * @since 1.7
 * @author Blove maple
 */
public class CatnavGraphTemplate {
	private static final int MAX_GENES = 10;
	private static final int MAX_SIBLINGS = 10;
	private static final int GAP_GENES_LEFT = 2, GAP_GENES_RIGHT = 2;
	private static final int GAP_SIBLINGS = 1;

	private static final String ARG_SIBLINGS = "siblings";
	private static final String ARG_NAME = "item";
	private static final String VALUE_HOLINE = "-";
	private static final String ARG_POSTLINE = "postline";
	private static final int LINE_UP = 0b1000, LINE_DOWN = 0b100,
			LINE_LEFT = 0b10, LINE_RIGHT = 0b1;

	/**
	 * 生成并返回代码。
	 * 
	 * @return 模板代码
	 */
	private static String generate() {
		StringBuilder str = new StringBuilder();
		str.append("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">");
		for (int row = 0; row < MAX_SIBLINGS; row++)
			appendRow(str, row);
		str.append("</table>");
		return str.toString();
	}

	private static void appendRow(StringBuilder str, int rowIndex) {
		str.append("{{#ifexpr: " + rowNum() + " > " + rowIndex + " | ");

		str.append("<tr align=\"center\">");
		for (int item = 0; item < MAX_GENES; item++)
			appendBlockInnerRow1(str, rowIndex, item);
		str.append("</tr>");

		str.append("<tr>");
		for (int item = 0; item < MAX_GENES; item++)
			appendBlockInnerRow2(str, rowIndex, item);
		str.append("</tr>");

		str.append("{{#ifexpr: " + rowIndex + " < (" + rowNum() + "-1) | ");
		for (int innerRow = 0; innerRow < GAP_SIBLINGS; innerRow++) {
			str.append("<tr>");
			for (int item = 0; item < MAX_GENES; item++)
				appendSiblingsGapInnerRow(str, rowIndex, innerRow, item);
			str.append("</tr>");
		}
		str.append("}}");

		str.append("}}");
	}

	private static void appendBlockInnerRow1(StringBuilder str, int rowIndex,
			int columnIndex) {
		str.append("<td {{#ifeq: {{{"
				+ ARG_NAME
				+ rowIndex
				+ columnIndex
				+ "}}} | "
				+ VALUE_HOLINE
				+ " | style=\"border-bottom: 1px solid black;\" | rowspan=\"2\" }} > {{#ifeq: {{{"
				+ ARG_NAME + rowIndex + columnIndex + "}}} | " + VALUE_HOLINE
				+ " | | <div style=\"line-height:100%; height:1em;\"> "
				+ catLink("{{{" + ARG_NAME + rowIndex + columnIndex + "|}}}")
				+ " </div> }} </td>");
		for (int time = 0; time < GAP_GENES_LEFT + GAP_GENES_RIGHT; time++)
			str.append("<td style=\" {{#ifexpr: "
					+ ((time < GAP_GENES_LEFT) ? lineCon(rowIndex, columnIndex,
							LINE_LEFT) : lineCon(rowIndex, columnIndex,
							LINE_RIGHT))
					+ " | border-bottom: 1px solid black; }} "
					+ ((time == GAP_GENES_LEFT - 1) ? " {{#ifexpr: "
							+ lineCon(rowIndex, columnIndex, LINE_UP)
							+ "| border-right: 1px solid black; }}" : "")
					+ "\" > <div style=\"width: 0.5em; height: 0.5em;\"></div></td>");
	}

	private static void appendBlockInnerRow2(StringBuilder str, int rowIndex,
			int columnIndex) {
		str.append("{{#ifeq: {{{" + ARG_NAME + rowIndex + columnIndex
				+ "}}} | " + VALUE_HOLINE + " | <td></td> | }}");
		for (int time = 0; time < GAP_GENES_LEFT + GAP_GENES_RIGHT; time++)
			str.append("<td "
					+ ((time == GAP_GENES_LEFT - 1) ? "{{#ifexpr: "
							+ lineCon(rowIndex, columnIndex, LINE_DOWN)
							+ " | style=\"border-right: 1px solid black;\" }}"
							: "")
					+ "> <div style=\"height: 0.5em;\"></div></td>");
	}

	private static void appendSiblingsGapInnerRow(StringBuilder str,
			int rowIndex, int innerRowIndex, int columnIndex) {
		str.append("<td></td>");
		for (int time = 0; time < GAP_GENES_LEFT + GAP_GENES_RIGHT; time++)
			str.append("<td "
					+ ((time == GAP_GENES_LEFT - 1) ? "{{#ifexpr: "
							+ lineCon(rowIndex, columnIndex, LINE_DOWN)
							+ " | style=\"border-right: 1px solid black;\" }}"
							: "")
					+ "> <div style=\"height: 0.5em;\"></div></td>");
	}

	private static String lineCon(int rowIndex, int columnIndex, int mask) {
		return "{{{" + ARG_POSTLINE + rowIndex + columnIndex + "|0}}} mod "
				+ (mask << 1) + " >= " + mask;
	}

	private static String catLink(String cat) {
		return "{{#ifexist: Category:" + cat + " | [[:Category:" + cat + "|"
				+ cat + "]] | " + cat + "}}";
	}

	private static String rowNum() {
		return "{{#if: {{{" + ARG_SIBLINGS + "|}}} | {{#ifexpr: {{{"
				+ ARG_SIBLINGS + "}}} <= " + MAX_SIBLINGS + " | {{{"
				+ ARG_SIBLINGS + "}}} | " + MAX_SIBLINGS + " }} | "
				+ MAX_SIBLINGS + " }}";
	}

	/**
	 * 测试
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(generate());
	}
}