Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add generation of virtual method signatures.

  • Loading branch information...
commit 4404f9c20b1d8cd6dc01c1cfde7ce2a78347e7b6 1 parent 58825fa
@angavrilov authored
Showing with 528 additions and 42 deletions.
  1. +78 −6 codegen.pl
  2. +360 −13 df.items.xml
  3. +68 −17 lower-1.xslt
  4. +22 −6 lower-2.xslt
View
84 codegen.pl
@@ -529,7 +529,7 @@ ($;%)
}
my %atable = ( 1 => 'char', 2 => 'short', 4 => 'int' );
-
+
my %custom_container_handlers = (
'stl-vector' => sub {
my $item = get_container_item_type($_, -void => 'void*');
@@ -681,6 +681,82 @@ sub emit_find_instance {
}
}
+sub render_virtual_methods {
+ my ($tag) = @_;
+
+ my @parents = ( $tag );
+ for (;;) {
+ my $inherits = $parents[0]->getAttribute('inherits-from') or last;
+ my $parent = $types{$inherits} || die "Unknown parent: $inherits\n";
+ unshift @parents, $parent;
+ }
+
+ my %name_index;
+ my @vtable;
+ my @starts;
+ my $dtor_id = '~destructor';
+
+ for my $type (@parents) {
+ push @starts, scalar(@vtable);
+ for my $method ($type->findnodes('virtual-methods/vmethod')) {
+ my $is_destructor = is_attr_true($method, 'is-destructor');
+ my $name = $is_destructor ? $dtor_id : $method->getAttribute('name');
+ if ($name) {
+ die "Duplicate method: $name in ".$type->getAttribute('type-name')."\n"
+ if exists $name_index{$name};
+ $name_index{$name} = scalar(@vtable);
+ }
+ push @vtable, $method;
+ }
+ }
+
+ my $dtor_idx = $name_index{$dtor_id};
+ unless (defined $dtor_idx) {
+ for (my $i = 0; $i <= $#vtable; $i++) {
+ next if $vtable[$i]->getAttribute('name');
+ $name_index{$dtor_id} = $dtor_idx = $i;
+ last;
+ }
+ }
+ unless (defined $dtor_idx) {
+ push @vtable, undef;
+ $dtor_idx = $#vtable;
+ }
+
+ my $min_id = $starts[-1];
+ my $cur_mode = '';
+ for (my $idx = $min_id; $idx <= $#vtable; $idx++) {
+ my $method = $vtable[$idx];
+ my $is_destructor = $method ? is_attr_true($method, 'is-destructor') : 1;
+ my $name = $is_destructor ? $typename : $method->getAttribute('name');
+
+ my $rq_mode = ($method && $name) ? 'public' : 'protected';
+ unless ($rq_mode eq $cur_mode) {
+ $cur_mode = $rq_mode;
+ outdent { emit "$cur_mode:"; }
+ }
+
+ if ($idx == $dtor_idx) {
+ $is_destructor = 1;
+ $name = $typename;
+ }
+
+ with_anon {
+ $name = ensure_name $name;
+ my @ret_type = $is_destructor ? () : $method->findnodes('ret-type');
+ my @arg_types = $is_destructor ? () : $method->findnodes('ld:field');
+ my $ret_type = $ret_type[0] ? get_struct_field_type($ret_type[0]) : 'void';
+ my $ret_stmt = '';
+ unless ($ret_type eq 'void') {
+ $ret_stmt = ' return '.($ret_type =~ /\*$/ ? '0' : "$ret_type()").'; ';
+ }
+ $ret_type = $is_destructor ? '~' : $ret_type.' ';
+ my @arg_strs = map { scalar get_struct_field_type($_) } @arg_types;
+ emit 'virtual ', $ret_type, $name, '(', join(', ', @arg_strs), ') {', $ret_stmt, '}; //', $idx;
+ } "anon_vmethod_$idx";
+ }
+}
+
sub render_struct_type {
my ($tag) = @_;
@@ -715,12 +791,8 @@ sub render_struct_type {
}
}
- outdent {
- emit "protected:";
- };
-
if ($is_class) {
- emit "virtual ~",$typename,"() {}";
+ render_virtual_methods $tag;
} else {
emit "~",$typename,"() {}";
}
View
373 df.items.xml
@@ -106,6 +106,351 @@
<int32_t name='weight' comment='if flags.weight_computed'/>
<int32_t name='weight_fraction' comment='1e-6'/>
+
+ <virtual-methods>
+ <vmethod ret-type='item_type' name='getType'/>
+ <vmethod ret-type='int16_t' name='getSubtype'/>
+ <vmethod ret-type='int16_t' name='getMaterial'/>
+ <vmethod ret-type='int32_t' name='getMaterialIndex'/>
+ <vmethod name='setSubtype'> <int16_t/> </vmethod>
+
+ <vmethod name='setMaterial'> <int16_t/> </vmethod>
+ <vmethod name='setMaterialIndex'> <int32_t/> </vmethod>
+ <vmethod ret-type='int16_t' name='getActualMaterial'
+ comment='returns an actual material type, never a race'/>
+ <vmethod ret-type='int32_t' name='getActualMaterialIndex'
+ comment='returns an actual material index, never a caste'/>
+ <vmethod ret-type='int16_t' name='getRace'
+ comment='only if the object is made of a "specific creature mat"'/>
+
+ -- 10
+
+ <vmethod ret-type='int16_t' name='getCaste'
+ comment='only if the object is made of a "specific creature mat"'/>
+ <vmethod ret-type='int16_t' name='getPlantID'
+ comment='only if the object is made of a plant material'/>
+ <vmethod ret-type='int32_t' name='getTotalDimension'/>
+ <vmethod name='setDimension'> <int32_t name='amount'/> </vmethod>
+ <vmethod ret-type='bool' name='decreaseDimension'> <int32_t name='amount'/> </vmethod>
+
+ <vmethod ret-type='bool' name='isFoodStorage'/>
+ <vmethod name='getStockpile'>
+ <ret-type><pointer type-name='item_stockpile_ref'/></ret-type>
+ </vmethod>
+ <vmethod ret-type='bool' name='containsPlaster'/>
+ <vmethod ret-type='bool' name='isPlaster'/>
+ <vmethod ret-type='bool' name='getColorOverride'> <pointer/> </vmethod>
+
+ -- 20
+
+ <vmethod name='getHistoryInfo'>
+ <ret-type><pointer><pointer type-name='item_history_info'/></pointer></ret-type>
+ </vmethod>
+ <vmethod ret-type='bool' name='hasToolUse'> <int16_t/> </vmethod>
+ <vmethod name='becomePaste'/>
+ <vmethod name='becomePressed'/>
+ <vmethod/>
+
+ <vmethod ret-type='bool' name='isSharpStone'/>
+ <vmethod ret-type='bool' name='isCrystalGlassable'/>
+ <vmethod ret-type='bool' name='isMetalOre'> <int16_t name='matIndex'/> </vmethod>
+ <vmethod/>
+ <vmethod/>
+
+ -- 30
+
+ <vmethod ret-type='uint16_t' name='getSpecHeat'/>
+ <vmethod ret-type='uint16_t' name='getIgnitePoint'/>
+ <vmethod ret-type='uint16_t' name='getHeatdamPoint'/>
+ <vmethod ret-type='uint16_t' name='getColddamPoint'/>
+ <vmethod ret-type='uint16_t' name='getBoilingPoint'/>
+
+ <vmethod ret-type='uint16_t' name='getMeltingPoint'/>
+ <vmethod ret-type='uint16_t' name='getFixedTemp'/>
+ <vmethod ret-type='int32_t' name='getSolidDensity'/>
+ <vmethod ret-type='bool' name='materialRots'/>
+ <vmethod ret-type='uint16_t' name='getTemperature'/>
+
+ -- 40
+
+ <vmethod ret-type='bool' name='adjustTemperature'>
+ <int16_t name='target'/>
+ <int32_t name='unk'/>
+ </vmethod>
+ <vmethod/>
+ <vmethod name='extinguish'/>
+ <vmethod ret-type='int8_t' name='getGloveHandedness'/>
+ <vmethod name='setGloveHandedness'> <int8_t/> </vmethod>
+
+ <vmethod ret-type='bool' name='isSpike'/>
+ <vmethod ret-type='bool' name='isScrew'/>
+ <vmethod ret-type='bool' name='isBuildMat'/>
+ <vmethod ret-type='bool' name='isTemperatureSafe'> <int8_t comment='1 fire, 2 magma'/> </vmethod>
+ <vmethod name='setRandSubtype'> <pointer/> </vmethod>
+
+ -- 50
+
+ <vmethod/>
+ <vmethod ret-type='int16_t' name='getWear'/>
+ <vmethod name='setWear'> <int16_t/> </vmethod>
+ <vmethod ret-type='int32_t' name='getMaker'/>
+ <vmethod name='setMaker'> <int32_t name='unit_id'/> </vmethod>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod name='getGloveFlags'>
+ <ret-type><pointer><df-flagarray/></pointer></ret-type>
+ </vmethod>
+ <vmethod name='getItemShapeDesc' comment='a statue/figurine of "string goes here"'>
+ <ret-type><pointer type-name='stl-string'/></ret-type>
+ </vmethod>
+ <vmethod/>
+
+ -- 60
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod name='ageItem'><int32_t name='amount'/></vmethod>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='int32_t' name='getRotTimer'/>
+ <vmethod name='setRotTimer'> <int32_t name='val'/> </vmethod>
+ <vmethod name='incrementRotTimer'/>
+
+ -- 70
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod name='getAmmoType'>
+ <ret-type><pointer type-name='stl-string'/></ret-type>
+ <pointer type-name='stl-string'/>
+ </vmethod>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isLiquid'/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isMillable'/>
+
+ -- 80
+
+ <vmethod ret-type='bool' name='isProcessableThread'/>
+ <vmethod ret-type='bool' name='isProcessableVial'/>
+ <vmethod ret-type='bool' name='isProcessableBag'/>
+ <vmethod ret-type='bool' name='isProcessableBarrel'/>
+ <vmethod ret-type='bool' name='isEdiblePlant'/>
+
+ <vmethod ret-type='bool' name='isEdibleRaw'> <int32_t name='hunger'/> </vmethod>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 90
+
+ <vmethod/>
+ <vmethod ret-type='bool' name='isPressed'/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 100
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='needTwoHandedWield'> <int32_t/> </vmethod>
+ <vmethod name='splitStack'>
+ <ret-type><pointer type-name='item'/></ret-type>
+ <int32_t/>
+ <int32_t/>
+ </vmethod>
+ <vmethod ret-type='bool' name='isTameableVermin'/>
+
+ <vmethod ret-type='bool' name='isDistillable'>
+ <bool name='checkKitchenSettings'/>
+ </vmethod>
+ <vmethod ret-type='bool' name='isDye'/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isSandBearing'/>
+ <vmethod ret-type='bool' name='isLyeBearing'/>
+
+ -- 110
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 120
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod name='write_file'> <pointer comment='file_compressorst'/> </vmethod>
+ <vmethod name='read_file'>
+ <pointer comment='file_compressorst'/>
+ <int32_t name='loadversion'/>
+ </vmethod>
+
+ <vmethod name='getWeaponAttacks'>
+ <ret-type><stl-vector type-name='pointer'/></ret-type>
+ </vmethod>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 130
+
+ <vmethod/>
+ <vmethod ret-type='bool' name='isBag' comment='BOX made of cloth'/>
+ <vmethod ret-type='bool' name='isSand'/>
+ <vmethod ret-type='int32_t' name='getStackSize'/>
+ <vmethod name='addStackSize'> <int32_t name='amount'/> </vmethod>
+
+ <vmethod name='setStackSize'> <int32_t name='amount'/> </vmethod>
+ <vmethod ret-type='bool' name='isAmmoClass'> <pointer type-name='stl-string'/> </vmethod>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 140
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='int16_t' name='getMeleeSkill'/>
+ <vmethod ret-type='int16_t' name='getRangedSkill'/>
+
+ -- 150
+
+ <vmethod name='setQuality'> <int16_t name='quality'/> </vmethod>
+ <vmethod ret-type='int16_t' name='getQuality'/>
+ <vmethod ret-type='int16_t' name='getOverallQuality'/>
+ <vmethod ret-type='int16_t' name='getImprovementQuality'/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod name='setSharpness'>
+ <int32_t name='unk1'/>
+ <int32_t name='unk2'/>
+ </vmethod>
+ <vmethod ret-type='int32_t' name='getSharpness'/>
+ <vmethod ret-type='bool' name='isTotemable'/>
+ <vmethod ret-type='bool' name='isDyeable'/>
+
+ -- 160
+
+ <vmethod ret-type='bool' name='isUndyed'/>
+ <vmethod ret-type='bool' name='isDyed'/>
+ <vmethod ret-type='bool' name='canSewImage'/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isProcessableVialAtStill'/>
+
+ <vmethod/>
+ <vmethod ret-type='int32_t' name='getBlockChance'/>
+ <vmethod/>
+ <vmethod ret-type='int16_t' name='getMakerRace'/>
+ <vmethod/>
+
+ -- 170
+
+ <vmethod ret-type='int8_t' name='getEffectiveArmorLevel'
+ comment="adds 1 if it has [METAL_ARMOR_LEVELS] and it's made of an inorganic mat"/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isOrganicCloth'/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod ret-type='bool' name='isImproved'/>
+ <vmethod/>
+ <vmethod name='getItemDescription'>
+ <pointer type-name='stl-string'/>
+ <int8_t name='mode'/>
+ </vmethod>
+ <vmethod/>
+
+ -- 180
+
+ <vmethod/>
+ <vmethod ret-type='bool' name='isExtractBearingFish'/>
+ <vmethod ret-type='bool' name='isExtractBearingVermin'/>
+ <vmethod ret-type='int32_t' name='getBaseWeight'/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isEdibleVermin'/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isRangedWeapon'/>
+
+ -- 190
+
+ <vmethod ret-type='bool' name='isClothing'/>
+ <vmethod ret-type='bool' name='isWet'/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod name='getStockpile2'>
+ <ret-type><pointer type-name='item_stockpile_ref'/></ret-type>
+ </vmethod>
+ <vmethod/>
+ <vmethod/>
+
+ -- 200
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+
+ -- 210
+
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod/>
+ <vmethod ret-type='bool' name='isEngraved' comment='slabs only'/>
+
+ <vmethod ret-type='int32_t' name='getAbsorption'/>
+ <vmethod/>
+ <vmethod is-destructor='true'/>
+ </virtual-methods>
</class-type>
-- ACTUAL ITEM
@@ -121,6 +466,12 @@
<stl-vector name="slayer_kill_counts" type-name='int32_t'/>
</struct-type>
+ <struct-type type-name='item_history_info'>
+ <pointer name='kills' type-name='item_kill_info'/>
+ <int32_t name='unk1'/>
+ <int32_t name='unk2'/>
+ </struct-type>
+
<class-type type-name='item_actual' inherits-from='item' original-name='item_actualst'>
<int32_t name='stack_size'/>
@@ -130,11 +481,7 @@
</code-helper>
<pointer name='history_info'>
- <pointer>
- <pointer name='kills' type-name='item_kill_info'/>
- <int32_t name='unk1'/>
- <int32_t name='unk2'/>
- </pointer>
+ <pointer type-name='item_history_info'/>
</pointer>
<pointer name='unk5'>
@@ -481,20 +828,20 @@
<class-type type-name='item_toolst' inherits-from='item_constructed'>
<pointer name='subtype' type-name='itemdef_toolst'/>
<int32_t name='sharpness'/>
- <int32_t name='unk_a8'/>
- <int16_t name='unk_ac'/>
- <int16_t name='unk_ae'/>
+ <compound name='stockpile' type-name='item_stockpile_ref'/>
</class-type>
- <class-type type-name='item_barrelst' inherits-from='item_constructed'>
- <int32_t name='stockpile' ref-target='building'/>
+ <struct-type type-name='item_stockpile_ref'>
+ <int32_t name='id' ref-target='building'/>
<int16_t name='x'/>
<int16_t name='y'/>
+ </struct-type>
+
+ <class-type type-name='item_barrelst' inherits-from='item_constructed'>
+ <compound name='stockpile' type-name='item_stockpile_ref'/>
</class-type>
<class-type type-name='item_binst' inherits-from='item_constructed'>
- <int32_t name='stockpile' ref-target='building'/>
- <int16_t name='x'/>
- <int16_t name='y'/>
+ <compound name='stockpile' type-name='item_stockpile_ref'/>
</class-type>
<class-type type-name='item_statuest' inherits-from='item_constructed'>
View
85 lower-1.xslt
@@ -34,8 +34,19 @@
</ld:data-definition>
</xsl:template>
- <xsl:template match="comment|code-helper|enum-attr|enum-item">
- <xsl:copy-of select='.'/>
+ <xsl:template match="comment|code-helper|enum-attr|enum-item|item-attr">
+ <xsl:copy>
+ <xsl:apply-templates select='@*|node()'/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="virtual-methods|cond-if|cond-else">
+ <xsl:param name='level' select='-1'/>
+ <xsl:copy>
+ <xsl:apply-templates select='@*|node()'>
+ <xsl:with-param name='level' select="$level"/>
+ </xsl:apply-templates>
+ </xsl:copy>
</xsl:template>
<!-- Type defs: convert to one common 'global-type' tag name. -->
@@ -120,25 +131,34 @@
- When an ad-hoc compound: meta='compound' subtype='$tag'
- Level not incremented unless it has a name.
-->
+ <xsl:template name='compound'>
+ <xsl:param name='level' select='-1'/>
+ <xsl:param name='level_shift' select='1'/>
+ <xsl:attribute name='ld:level'><xsl:value-of select='$level'/></xsl:attribute>
+ <xsl:choose>
+ <xsl:when test='@type-name'>
+ <xsl:call-template name='lookup-type-ref'>
+ <xsl:with-param name='name' select="@type-name"/>
+ </xsl:call-template>
+ <xsl:apply-templates select='@*|node()'/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name='ld:meta'>compound</xsl:attribute>
+ <xsl:apply-templates select='@*|node()'>
+ <xsl:with-param name='level' select="$level+$level_shift"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
<xsl:template match='compound|bitfield|enum'>
<xsl:param name='level' select='-1'/>
<ld:field>
- <xsl:attribute name='ld:level'><xsl:value-of select='$level'/></xsl:attribute>
<xsl:attribute name='ld:subtype'><xsl:value-of select='name(.)'/></xsl:attribute>
- <xsl:choose>
- <xsl:when test='@type-name'>
- <xsl:call-template name='lookup-type-ref'>
- <xsl:with-param name='name' select="@type-name"/>
- </xsl:call-template>
- <xsl:apply-templates select='@*|node()'/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:attribute name='ld:meta'>compound</xsl:attribute>
- <xsl:apply-templates select='@*|node()'>
- <xsl:with-param name='level' select="$level+count(@name)"/>
- </xsl:apply-templates>
- </xsl:otherwise>
- </xsl:choose>
+ <xsl:call-template name='compound'>
+ <xsl:with-param name='level' select="$level"/>
+ <xsl:with-param name='level_shift' select="count(@name)"/>
+ </xsl:call-template>
</ld:field>
</xsl:template>
@@ -190,6 +210,37 @@
</xsl:call-template>
</ld:field>
</xsl:template>
+
+ <!-- Virtual methods -->
+
+ <xsl:template match='vmethod'>
+ <xsl:param name='level' select='-1'/>
+ <xsl:copy>
+ <xsl:attribute name='ld:level'><xsl:value-of select='$level'/></xsl:attribute>
+ <xsl:apply-templates select='@*'/>
+ <xsl:if test='@ret-type'>
+ <xsl:copy-of select='text()[1]'/>
+ <ret-type>
+ <xsl:attribute name='ld:level'><xsl:value-of select='$level+1'/></xsl:attribute>
+ <xsl:call-template name='lookup-type-ref'>
+ <xsl:with-param name='name' select="@ret-type"/>
+ </xsl:call-template>
+ </ret-type>
+ </xsl:if>
+ <xsl:apply-templates select='node()'>
+ <xsl:with-param name='level' select="$level+1"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match='ret-type'>
+ <xsl:param name='level' select='-1'/>
+ <xsl:copy>
+ <xsl:call-template name='compound'>
+ <xsl:with-param name='level' select="$level"/>
+ </xsl:call-template>
+ </xsl:copy>
+ </xsl:template>
</xsl:stylesheet>
<!--
View
28 lower-2.xslt
@@ -8,6 +8,7 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ld="http://github.com/peterix/dfhack/lowered-data-definition">
+ <!-- Generic walk -->
<xsl:template match="@*">
<xsl:copy-of select='.'/>
</xsl:template>
@@ -18,31 +19,40 @@
</xsl:copy>
</xsl:template>
+ <!-- Detect invalid fields & methods -->
<xsl:template match="ld:field[not(@ld:level) or (@ld:level &lt; 0)]" priority='10'>
<xsl:message terminate='yes'>
Unexpected field: <xsl:copy-of select='.'/>
</xsl:message>
</xsl:template>
+ <xsl:template match="ld:vmethod[not(@ld:level) or not(@ld:level = 1)]" priority='10'>
+ <xsl:message terminate='yes'>
+ Unexpected method: <xsl:copy-of select='.'/>
+ </xsl:message>
+ </xsl:template>
+
+ <!-- Unify containers -->
<xsl:template match="ld:field" priority='8'>
- <xsl:param name="tag" select="'field'"/>
- <xsl:element name='ld:{$tag}'>
+ <xsl:param name="tag" select="name(.)"/>
+ <xsl:element name='{$tag}'>
<xsl:apply-templates select='@*|node()'/>
</xsl:element>
</xsl:template>
- <xsl:template match="ld:field[@ld:is-container]" priority='9'>
- <xsl:param name="tag" select="'field'"/>
- <xsl:element name='ld:{$tag}'>
+ <xsl:template match="*[@ld:is-container]" priority='9'>
+ <xsl:param name="tag" select="name(.)"/>
+ <xsl:element name='{$tag}'>
<xsl:apply-templates select='@*'/>
<xsl:choose>
<xsl:when test='count(ld:field) &lt;= 1'>
<xsl:apply-templates select='node()'>
- <xsl:with-param name='tag' select="'item'"/>
+ <xsl:with-param name='tag' select="'ld:item'"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<!-- This destroys formatting, but it seems inevitable. -->
+ <xsl:copy-of select='text()[1]'/>
<ld:item ld:meta='compound'>
<xsl:attribute name='ld:level'><xsl:value-of select='@ld:level'/></xsl:attribute>
<xsl:apply-templates select='ld:field|text()'/>
@@ -52,6 +62,12 @@
</xsl:choose>
</xsl:element>
</xsl:template>
+
+ <xsl:template match='ret-type[count(ld:field)=1]'>
+ <xsl:apply-templates select='ld:field'>
+ <xsl:with-param name='tag' select="'ret-type'"/>
+ </xsl:apply-templates>
+ </xsl:template>
</xsl:stylesheet>
<!--
Please sign in to comment.
Something went wrong with that request. Please try again.