Accepting request 321596 from home:sndirsch:fate318355
- genmap4systemd.sh: use 'abnt2' model for 'br' layouts, 'jp106' model for 'jp' layouts and 'microsoftpro' for anything else (instead of 'pc105' before) (FATE#318426) - added genmap4systemd.sh tool, which generates entries for systemd's /usr/share/systemd/kbd-model-map table from xkeyboard-config converted keymaps; entries are written to /usr/share/systemd/kbd-model-map.xkb-generated, so these can easily be added to /usr/share/systemd/kbd-model-map by systemd package (FATE#318426) - Include xkb layouts from xkeyboard-config converted to console keymaps, (FATE#318426) * Rename Finnish xkb converted layout * Add xkb and legacy keymaps subdirs to loadkyes search path, remove symlinks, Don't convert layouts that can't input ASCII, * Original keymaps moved to legacy dir, created symlinks to xkb keymaps OBS-URL: https://build.opensuse.org/request/show/321596 OBS-URL: https://build.opensuse.org/package/show/Base:System/kbd?expand=0&rev=77
This commit is contained in:
parent
f1d7273bde
commit
fc229be082
70
genmap4systemd.sh
Normal file
70
genmap4systemd.sh
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Generate entries for systemd's /usr/share/systemd/kbd-model-map
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
pushd /usr/share/kbd/keymaps/xkb > /dev/null || exit 1
|
||||||
|
else
|
||||||
|
pushd > /dev/null $1 || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "# generated from xkb generated keymaps (basic layouts *without* variant)"
|
||||||
|
for i in $(ls *.map.gz|grep -v "-"); do
|
||||||
|
consolelayout=$(echo $i|sed 's/.map.gz//g')
|
||||||
|
layout=$consolelayout
|
||||||
|
variant="-"
|
||||||
|
printf '%s' "$consolelayout"
|
||||||
|
printf "\t\t\t"
|
||||||
|
printf '%s' "$layout"
|
||||||
|
printf '\t'
|
||||||
|
printf 'microsoftpro\t\t'
|
||||||
|
printf '%s' "$variant"
|
||||||
|
printf '\t\t'
|
||||||
|
printf 'terminate:ctrl_alt_bksp\n'
|
||||||
|
done | sort -u
|
||||||
|
|
||||||
|
echo "# generated from xkb generated keymaps (layouts *with* variant)"
|
||||||
|
for i in $(ls *-*.map.gz); do
|
||||||
|
consolelayout=$(echo $i|sed 's/.map.gz//g')
|
||||||
|
conlen=$(echo "$consolelayout" |wc -m)
|
||||||
|
conlen=$((conlen - 1))
|
||||||
|
|
||||||
|
layout=$(echo $i|cut -d "-" -f 1)
|
||||||
|
|
||||||
|
variant=$(echo $i|cut -d "-" -f 2,3,4,5,6,7,8,9,10|cut -d "." -f1)
|
||||||
|
varlen=$(echo $variant|wc -m)
|
||||||
|
varlen=$((varlen -1))
|
||||||
|
|
||||||
|
printf '%s' "$consolelayout"
|
||||||
|
if [ $conlen -lt 8 ]; then
|
||||||
|
printf "\t\t\t"
|
||||||
|
elif [ $conlen -lt 16 ]; then
|
||||||
|
printf "\t\t"
|
||||||
|
elif [ $conlen -lt 24 ]; then
|
||||||
|
printf "\t"
|
||||||
|
else
|
||||||
|
printf ' '
|
||||||
|
fi
|
||||||
|
printf '%s' "$layout"
|
||||||
|
printf '\t'
|
||||||
|
if [ "$layout" == "br" ]; then
|
||||||
|
printf 'abnt2\t\t'
|
||||||
|
elif [ "$layout" == "jp" ]; then
|
||||||
|
printf 'jp106\t\t'
|
||||||
|
else
|
||||||
|
printf 'microsoftpro\t\t'
|
||||||
|
fi
|
||||||
|
printf '%s' "$variant"
|
||||||
|
if [ $varlen -lt 8 ]; then
|
||||||
|
printf "\t\t"
|
||||||
|
elif [ $varlen -lt 16 ]; then
|
||||||
|
printf "\t"
|
||||||
|
else
|
||||||
|
printf ' '
|
||||||
|
fi
|
||||||
|
printf 'terminate:ctrl_alt_bksp\n'
|
||||||
|
|
||||||
|
done | sort -u
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
|
24
kbd-1.15.5-loadkeys-search-path.patch
Normal file
24
kbd-1.15.5-loadkeys-search-path.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
diff -up kbd-2.0.1/src/loadkeys.c.orig kbd-2.0.1/src/loadkeys.c
|
||||||
|
--- kbd-2.0.1/src/loadkeys.c.orig 2013-11-27 12:56:57.846069007 +0100
|
||||||
|
+++ kbd-2.0.1/src/loadkeys.c 2013-11-27 12:58:03.877302345 +0100
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
#include "keymap.h"
|
||||||
|
|
||||||
|
static const char *progname = NULL;
|
||||||
|
-static const char *const dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 };
|
||||||
|
+static const char *const dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", DATADIR "/" XKBKEYMAPDIR "/", DATADIR "/" LEGACYKEYMAPDIR "/**", KERNDIR "/", 0 };
|
||||||
|
static const char *const suffixes[] = { "", ".kmap", ".map", 0 };
|
||||||
|
|
||||||
|
static void __attribute__ ((noreturn))
|
||||||
|
diff -up kbd-2.0.1/src/paths.h.orig kbd-2.0.1/src/paths.h
|
||||||
|
--- kbd-2.0.1/src/paths.h.orig 2013-11-27 12:58:10.662326108 +0100
|
||||||
|
+++ kbd-2.0.1/src/paths.h 2013-11-27 12:58:32.566403015 +0100
|
||||||
|
@@ -5,6 +5,8 @@
|
||||||
|
* The following five subdirectories are defined:
|
||||||
|
*/
|
||||||
|
#define KEYMAPDIR "keymaps"
|
||||||
|
+#define XKBKEYMAPDIR "keymaps/xkb"
|
||||||
|
+#define LEGACYKEYMAPDIR "keymaps/legacy"
|
||||||
|
#define UNIMAPDIR "unimaps"
|
||||||
|
#define TRANSDIR "consoletrans"
|
||||||
|
#define VIDEOMODEDIR "videomodes"
|
28
kbd.changes
28
kbd.changes
@ -1,3 +1,31 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Aug 10 11:53:48 UTC 2015 - sndirsch@suse.com
|
||||||
|
|
||||||
|
- genmap4systemd.sh: use 'abnt2' model for 'br' layouts, 'jp106'
|
||||||
|
model for 'jp' layouts and 'microsoftpro' for anything else
|
||||||
|
(instead of 'pc105' before) (FATE#318426)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jul 21 10:05:35 UTC 2015 - sndirsch@suse.com
|
||||||
|
|
||||||
|
- added genmap4systemd.sh tool, which generates entries for
|
||||||
|
systemd's /usr/share/systemd/kbd-model-map table from
|
||||||
|
xkeyboard-config converted keymaps; entries are written to
|
||||||
|
/usr/share/systemd/kbd-model-map.xkb-generated, so these can
|
||||||
|
easily be added to /usr/share/systemd/kbd-model-map by systemd
|
||||||
|
package (FATE#318426)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Jul 17 12:54:27 UTC 2015 - sndirsch@suse.com
|
||||||
|
|
||||||
|
- Include xkb layouts from xkeyboard-config converted to console
|
||||||
|
keymaps, (FATE#318426)
|
||||||
|
* Rename Finnish xkb converted layout
|
||||||
|
* Add xkb and legacy keymaps subdirs to loadkyes search path,
|
||||||
|
remove symlinks, Don't convert layouts that can't input ASCII,
|
||||||
|
* Original keymaps moved to legacy dir, created symlinks to xkb
|
||||||
|
keymaps
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Apr 2 18:36:23 UTC 2015 - crrodriguez@opensuse.org
|
Thu Apr 2 18:36:23 UTC 2015 - crrodriguez@opensuse.org
|
||||||
|
|
||||||
|
65
kbd.spec
65
kbd.spec
@ -42,6 +42,8 @@ Source13: guess_encoding.pl
|
|||||||
Source14: kbd.pl
|
Source14: kbd.pl
|
||||||
Source42: convert-kbd-mac.sed
|
Source42: convert-kbd-mac.sed
|
||||||
Source43: repack_kbd.sh
|
Source43: repack_kbd.sh
|
||||||
|
Source44: xml2lst.pl
|
||||||
|
Source45: genmap4systemd.sh
|
||||||
Patch0: kbd-1.15.2-prtscr_no_sigquit.patch
|
Patch0: kbd-1.15.2-prtscr_no_sigquit.patch
|
||||||
Patch2: kbd-1.15.2-unicode_scripts.patch
|
Patch2: kbd-1.15.2-unicode_scripts.patch
|
||||||
Patch3: kbd-1.15.2-docu-X11R6-xorg.patch
|
Patch3: kbd-1.15.2-docu-X11R6-xorg.patch
|
||||||
@ -53,6 +55,9 @@ Patch9: kbd-2.0.2-comment-typo-qwerty.patch
|
|||||||
Patch10: kbd-2.0.2-doshell-reference.patch
|
Patch10: kbd-2.0.2-doshell-reference.patch
|
||||||
Patch11: kbd-2.0.2-euro-unicode.patch
|
Patch11: kbd-2.0.2-euro-unicode.patch
|
||||||
Patch12: kbd-2.0.2-fix-bashisms.patch
|
Patch12: kbd-2.0.2-fix-bashisms.patch
|
||||||
|
# Patch13: adds xkb and legacy keymaps subdirs to loadkyes search path
|
||||||
|
# (openSUSE FATE#318355, sle FATE#318426)
|
||||||
|
Patch13: kbd-1.15.5-loadkeys-search-path.patch
|
||||||
|
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
@ -63,7 +68,13 @@ BuildRequires: pam-devel
|
|||||||
BuildRequires: pkg-config
|
BuildRequires: pkg-config
|
||||||
BuildRequires: suse-module-tools
|
BuildRequires: suse-module-tools
|
||||||
BuildRequires: xz
|
BuildRequires: xz
|
||||||
|
|
||||||
|
BuildRequires: console-setup
|
||||||
|
BuildRequires: xkeyboard-config
|
||||||
|
|
||||||
Requires(pre): %fillup_prereq
|
Requires(pre): %fillup_prereq
|
||||||
|
# Temporarily require -legacy
|
||||||
|
Requires: %{name}-legacy = %{version}-%{release}
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
|
||||||
@ -82,10 +93,23 @@ Authors:
|
|||||||
Andries Brouwer <aeb@cwi.nl>
|
Andries Brouwer <aeb@cwi.nl>
|
||||||
Alexey Gladkov <gladkov.alexey@gmail.com>
|
Alexey Gladkov <gladkov.alexey@gmail.com>
|
||||||
|
|
||||||
|
%package legacy
|
||||||
|
Summary: Legacy data for kbd package
|
||||||
|
Group: System/Console
|
||||||
|
BuildArch: noarch
|
||||||
|
|
||||||
|
%description legacy
|
||||||
|
The %{name}-legacy package contains original keymaps for kbd package.
|
||||||
|
Please note that %{name}-legacy is not helpful without kbd.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%define kbd /usr/share/kbd
|
%define kbd /usr/share/kbd
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -a 1 -a 2 -n kbd-%{version}
|
%setup -q -a 1 -a 2 -n kbd-%{version}
|
||||||
|
cp -fp %{SOURCE44} .
|
||||||
|
cp -fp %{SOURCE45} .
|
||||||
%patch0 -p1
|
%patch0 -p1
|
||||||
%patch2
|
%patch2
|
||||||
%patch3
|
%patch3
|
||||||
@ -97,6 +121,7 @@ Authors:
|
|||||||
%patch10
|
%patch10
|
||||||
%patch11
|
%patch11
|
||||||
%patch12 -p1
|
%patch12 -p1
|
||||||
|
%patch13 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
for i in `find data/keymaps/mac -type f` ; do
|
for i in `find data/keymaps/mac -type f` ; do
|
||||||
@ -286,6 +311,40 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin
|
|||||||
ln -s %{_bindir}/resizecons %{buildroot}/bin
|
ln -s %{_bindir}/resizecons %{buildroot}/bin
|
||||||
%endif
|
%endif
|
||||||
#EndUsrMerge
|
#EndUsrMerge
|
||||||
|
|
||||||
|
# Move original keymaps to legacy directory
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/%{kbd}/keymaps/legacy
|
||||||
|
mv $RPM_BUILD_ROOT/%{kbd}/keymaps/{amiga,atari,i386,include,mac,ppc,sun} $RPM_BUILD_ROOT/%{kbd}/keymaps/legacy
|
||||||
|
|
||||||
|
# Convert X keyboard layouts to console keymaps
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb
|
||||||
|
perl xml2lst.pl < /usr/share/X11/xkb/rules/base.xml > layouts-variants.lst
|
||||||
|
while read line; do
|
||||||
|
XKBLAYOUT=`echo "$line" | cut -d " " -f 1`
|
||||||
|
echo "$XKBLAYOUT" >> layouts-list.lst
|
||||||
|
XKBVARIANT=`echo "$line" | cut -d " " -f 2`
|
||||||
|
ckbcomp "$XKBLAYOUT" "$XKBVARIANT" | gzip > $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/"$XKBLAYOUT"-"$XKBVARIANT".map.gz
|
||||||
|
done < layouts-variants.lst
|
||||||
|
|
||||||
|
# Convert X keyboard layouts (plain, no variant)
|
||||||
|
cat layouts-list.lst | sort -u >> layouts-list-uniq.lst
|
||||||
|
while read line; do
|
||||||
|
ckbcomp "$line" | gzip > $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/"$line".map.gz
|
||||||
|
done < layouts-list-uniq.lst
|
||||||
|
|
||||||
|
# wipe converted layouts which cannot input ASCII (rh#1031848)
|
||||||
|
zgrep -L "U+0041" $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/* | xargs rm -f
|
||||||
|
|
||||||
|
# Rename the converted default fi (kotoistus) layout (rh#1117891)
|
||||||
|
gunzip $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi.map.gz
|
||||||
|
mv $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi.map $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi-kotoistus.map
|
||||||
|
gzip $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi-kotoistus.map
|
||||||
|
|
||||||
|
# Generate entries for systemd's /usr/share/systemd/kbd-model-map
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/share/systemd
|
||||||
|
sh ./genmap4systemd.sh $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb \
|
||||||
|
> $RPM_BUILD_ROOT/usr/share/systemd/kbd-model-map.xkb-generated
|
||||||
|
|
||||||
%find_lang %{name}
|
%find_lang %{name}
|
||||||
|
|
||||||
%post
|
%post
|
||||||
@ -307,6 +366,7 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin
|
|||||||
%{_localstatedir}/adm/fillup-templates/sysconfig.console
|
%{_localstatedir}/adm/fillup-templates/sysconfig.console
|
||||||
%{_localstatedir}/adm/fillup-templates/sysconfig.keyboard
|
%{_localstatedir}/adm/fillup-templates/sysconfig.keyboard
|
||||||
%{kbd}
|
%{kbd}
|
||||||
|
%exclude %{kbd}/keymaps/legacy
|
||||||
#UsrMerge
|
#UsrMerge
|
||||||
/sbin/fbtest
|
/sbin/fbtest
|
||||||
/bin/chvt
|
/bin/chvt
|
||||||
@ -423,5 +483,10 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin
|
|||||||
%doc %{_mandir}/man8/setvesablank.8.gz
|
%doc %{_mandir}/man8/setvesablank.8.gz
|
||||||
%doc %{_mandir}/man8/setvtrgb.8.gz
|
%doc %{_mandir}/man8/setvtrgb.8.gz
|
||||||
%doc %{_mandir}/man8/vcstime.8.gz
|
%doc %{_mandir}/man8/vcstime.8.gz
|
||||||
|
%dir /usr/share/systemd
|
||||||
|
/usr/share/systemd/kbd-model-map.xkb-generated
|
||||||
|
|
||||||
|
%files legacy
|
||||||
|
%{kbd}/keymaps/legacy
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
231
xml2lst.pl
Normal file
231
xml2lst.pl
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
# converts the <rules>.xml file to the old format <rules>.lst file
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# perl xml2lst.pl < filename.xml > filename.lst
|
||||||
|
#
|
||||||
|
# author Ivan Pascal
|
||||||
|
# modified by Vitezslav Crhonek
|
||||||
|
|
||||||
|
$doc = new_document( 0, '');
|
||||||
|
parse('', $doc);
|
||||||
|
|
||||||
|
($reg) = node_by_name($doc, '/xkbConfigRegistry');
|
||||||
|
@models = node_by_name($reg, 'modelList/model/configItem');
|
||||||
|
@layouts = node_by_name($reg, 'layoutList/layout/configItem');
|
||||||
|
@options = node_by_name($reg, 'optionList/group/configItem');
|
||||||
|
|
||||||
|
for $i (@layouts) {
|
||||||
|
($name) = node_by_name($i, 'name');
|
||||||
|
@variants = node_by_name($i, '../variantList/variant/configItem');
|
||||||
|
for $v (@variants) {
|
||||||
|
($variant) = node_by_name($v, 'name');
|
||||||
|
printf("%s %s\n", text_child($name), text_child($variant));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub with_attribute {
|
||||||
|
local ($nodelist, $attrexpr) = @_;
|
||||||
|
local ($attr, $value) = split (/=/, $attrexpr);
|
||||||
|
local ($node, $attrvalue);
|
||||||
|
if (defined $value && $value ne '') {
|
||||||
|
$value =~ s/"//g;
|
||||||
|
foreach $node (@{$nodelist}) {
|
||||||
|
$attrvalue = node_attribute($node, $attr);
|
||||||
|
if (defined $attrvalue && $attrvalue eq $value) {
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach $node (@{$nodelist}) {
|
||||||
|
if (! defined node_attribute($node, $attr)) {
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Subroutines
|
||||||
|
|
||||||
|
sub parse {
|
||||||
|
local $intag = 0;
|
||||||
|
my (@node_stack, $parent);
|
||||||
|
$parent = @_[1];
|
||||||
|
local ($tag, $text);
|
||||||
|
|
||||||
|
while (<>) {
|
||||||
|
chomp;
|
||||||
|
@str = split /([<>])/;
|
||||||
|
shift @str if ($str[0] eq '' || $str[0] =~ /^[ \t]*$/);
|
||||||
|
|
||||||
|
while (scalar @str) {
|
||||||
|
$token = shift @str;
|
||||||
|
if ($token eq '<') {
|
||||||
|
$intag = 1;
|
||||||
|
if (defined $text) {
|
||||||
|
add_text_node($parent, $text);
|
||||||
|
undef $text;
|
||||||
|
}
|
||||||
|
} elsif ($token eq '>') {
|
||||||
|
$intag = 0;
|
||||||
|
if ($tag =~ /^\/(.*)/) { # close tag
|
||||||
|
$parent = pop @node_stack;
|
||||||
|
} elsif ($tag =~ /^([^\/]*)\/$/) {
|
||||||
|
empty_tag($parent, $1);
|
||||||
|
} else {
|
||||||
|
if (defined ($node = open_tag($parent, $tag))) {
|
||||||
|
push @node_stack, $parent;
|
||||||
|
$parent = $node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
undef $tag;
|
||||||
|
} else {
|
||||||
|
if ($intag == 1) {
|
||||||
|
if (defined $tag) {
|
||||||
|
$tag .= ' '. $token;
|
||||||
|
} else {
|
||||||
|
$tag = $token;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (defined $text) {
|
||||||
|
$text .= "\n" . $token;
|
||||||
|
} else {
|
||||||
|
$text = $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub new_document {
|
||||||
|
$doc = new_node( 0, '', 'DOCUMENT');
|
||||||
|
$doc->{CHILDREN} = [];
|
||||||
|
return $doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub new_node {
|
||||||
|
local ($parent_node, $tag, $type) = @_;
|
||||||
|
|
||||||
|
my %node;
|
||||||
|
$node{PARENT} = $parent_node;
|
||||||
|
$node{TYPE} = $type;
|
||||||
|
|
||||||
|
if ($type eq 'COMMENT' || $type eq 'TEXT') {
|
||||||
|
$node{TEXT} = $tag;
|
||||||
|
$node{NAME} = $type;
|
||||||
|
return \%node;
|
||||||
|
}
|
||||||
|
|
||||||
|
local ($tname, $attr) = split(' ', $tag, 2);
|
||||||
|
$node{NAME} = $tname;
|
||||||
|
|
||||||
|
if (defined $attr && $attr ne '') {
|
||||||
|
my %attr_table;
|
||||||
|
local @attr_list = split ( /"/, $attr);
|
||||||
|
local ($name, $value);
|
||||||
|
while (scalar @attr_list) {
|
||||||
|
$name = shift @attr_list;
|
||||||
|
$name =~ s/[ =]//g;
|
||||||
|
next if ($name eq '');
|
||||||
|
$value = shift @attr_list;
|
||||||
|
$attr_table{$name} =$value;
|
||||||
|
}
|
||||||
|
$node{ATTRIBUTES} = \%attr_table;
|
||||||
|
}
|
||||||
|
return \%node;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_node {
|
||||||
|
local ($parent_node, $node) = @_;
|
||||||
|
push @{$parent_node->{CHILDREN}}, $node;
|
||||||
|
|
||||||
|
local $tname = $node->{NAME};
|
||||||
|
if (defined $parent_node->{$tname}) {
|
||||||
|
push @{$parent_node->{$tname}}, $node
|
||||||
|
} else {
|
||||||
|
$parent_node->{$tname} = [ $node ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub empty_tag {
|
||||||
|
local ($parent_node, $tag) = @_;
|
||||||
|
local $node = new_node($parent_node, $tag, 'EMPTY');
|
||||||
|
add_node($parent_node, $node);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub open_tag {
|
||||||
|
local ($parent_node, $tag) = @_;
|
||||||
|
local $node;
|
||||||
|
|
||||||
|
if ($tag =~ /^\?.*/ || $tag =~ /^\!.*/) {
|
||||||
|
$node = new_node($parent_node, $tag, 'COMMENT');
|
||||||
|
add_node($parent_node, $node);
|
||||||
|
undef; return;
|
||||||
|
} else {
|
||||||
|
$node = new_node($parent_node, $tag, 'NODE');
|
||||||
|
$node->{CHILDREN} = [];
|
||||||
|
add_node($parent_node, $node);
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_text_node {
|
||||||
|
local ($parent_node, $text) = @_;
|
||||||
|
local $node = new_node($parent_node, $text, 'TEXT');
|
||||||
|
add_node($parent_node, $node);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub node_by_name {
|
||||||
|
local ($node, $name) = @_;
|
||||||
|
local ($tagname, $path) = split(/\//, $name, 2);
|
||||||
|
|
||||||
|
my @nodelist;
|
||||||
|
|
||||||
|
if ($tagname eq '') {
|
||||||
|
while ($node->{PARENT} != 0) {
|
||||||
|
$node = $node->{PARENT};
|
||||||
|
}
|
||||||
|
sublist_by_name($node, $path, \@nodelist);
|
||||||
|
} else {
|
||||||
|
sublist_by_name($node, $name, \@nodelist);
|
||||||
|
}
|
||||||
|
return @nodelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sublist_by_name {
|
||||||
|
local ($node, $name, $res) = @_;
|
||||||
|
local ($tagname, $path) = split(/\//, $name, 2);
|
||||||
|
|
||||||
|
if (! defined $path) {
|
||||||
|
push @{$res}, (@{$node->{$tagname}});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tagname eq '..' && $node->{PARENT} != 0) {
|
||||||
|
$node = $node->{PARENT};
|
||||||
|
sublist_by_name($node, $path, $res);
|
||||||
|
} else {
|
||||||
|
local $n;
|
||||||
|
for $n (@{$node->{$tagname}}) {
|
||||||
|
sublist_by_name($n, $path, $res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub node_attribute {
|
||||||
|
local $node = @_[0];
|
||||||
|
if (defined $node->{ATTRIBUTES}) {
|
||||||
|
return $node->{ATTRIBUTES}{@_[1]};
|
||||||
|
}
|
||||||
|
undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub text_child {
|
||||||
|
local ($node) = @_;
|
||||||
|
local ($child) = node_by_name($node, 'TEXT');
|
||||||
|
return $child->{TEXT};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user