#!/usr/local/bin/perl package w3mdoc; sub CHECK { my($a, @b) = @_; for(@b) { defined($a->{$_}) || die("\"$a->{id}.$_\" is not defined.\n"); } } sub DEF { my($a, $b, $c) = @_; if (! defined($data->{$a})) { $data->{$a} = bless { id => $a }; } $data->{$a}{$b} = $c; } sub SUB { local($_) = @_; my($a, $b); if (/^\@(\w+)\.(\w+)\@$/) { ($a, $b) = ($1, $2); defined($data->{$a}) || die("\"$a.$b\" is not defined.\n"); $data->{$a}->CHECK($b); return $data->{$a}{$b}; } if (/^\@(\w+)\((\w+)\)\@$/) { ($a, $b) = ($1, $2); defined(&{$a}) || die("\"$a()\" is not defined.\n"); defined($data->{$b}) || die("\"$a($b)\" is not defined.\n"); return $data->{$b}->$a(); } return '@'; } package main; @ARGV || unshift(@ARGV, "-"); while(@ARGV) { $file = shift @ARGV; &make_doc($file); } sub make_doc { my($file) = @_; my($in_def, $in_code, $code, $a, $b); local(*F); local($_); open(F, $file) || die("$file: $!\n"); $in_def = 0; $in_code = 0; while() { if ($in_def) { if (/^\@end/) { $in_def = 0; next; } s/^\s+//; s/^(\w+)\.(\w+)// || next; ($a, $b) = ($1, $2); s/^\s+//; s/\s+$//; &w3mdoc::DEF($a, $b, $_); next; } if ($in_code) { if (/^\@end/) { eval "package w3mdoc; $code"; $in_code = 0; next; } $code .= $_; next; } if (/^\@define/) { $in_def = 1; next; } if (/^\@code/) { $in_code = 1; $code = ""; next; } if (s/^\@include\s+//) { s/\s+$//; &make_doc($_); next; } if (/^\@/) { die("unknown command: $_"); } s/(\\@|\@(\w+(\.\w+|\(\w+\)))\@)/&w3mdoc::SUB($1)/eg; print; } close(F); }