r65226 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r65225‎ | r65226 | r65227 >
Date:13:44, 18 April 2010
Author:siebrand
Status:ok
Tags:
Comment:
Rename extension folder per README.RDF.txt
Modified paths:
  • /trunk/extensions/RDF (deleted) (history)
  • /trunk/extensions/Rdf (added) (history)

Diff [purge]

Index: trunk/extensions/Rdf/rdfapi-php.mwrdf.diff
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/Rdf/rdfapi-php.mwrdf.diff
___________________________________________________________________
Name: svn:mime-type
11 + application/octet-stream
Name: svn:keywords
22 + Author Date Id Revision
Name: svn:eol-style
33 + native
Index: trunk/extensions/Rdf/Rdf.php
@@ -0,0 +1,1040 @@
 2+<?php
 3+/**
 4+ * MwRdf.php -- RDF framework for MediaWiki
 5+ * Copyright 2005, 2006 Evan Prodromou <evan@wikitravel.org>
 6+ *
 7+ * This program is free software; you can redistribute it and/or modify
 8+ * it under the terms of the GNU General Public License as published by
 9+ * the Free Software Foundation; either version 2 of the License, or
 10+ * (at your option) any later version.
 11+ *
 12+ * This program is distributed in the hope that it will be useful,
 13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15+ * GNU General Public License for more details.
 16+ *
 17+ * You should have received a copy of the GNU General Public License
 18+ * along with this program; if not, write to the Free Software
 19+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20+ *
 21+ * @author Evan Prodromou <evan@wikitravel.org>
 22+ * @ingroup Extensions
 23+ */
 24+if (defined('MEDIAWIKI')) {
 25+
 26+ require_once('GlobalFunctions.php');
 27+ if (!defined('RDFAPI_INCLUDE_DIR')) {
 28+ wfDebugDieBacktrace("MwRdf: you must install RAP (RDF API for PHP) " .
 29+ "and define 'RDFAPI_INCLUDE_DIR' in LocalSettings.php");
 30+ }
 31+ require_once(RDFAPI_INCLUDE_DIR . "RdfAPI.php");
 32+ require_once(RDFAPI_INCLUDE_DIR . PACKAGE_VOCABULARY);
 33+ require_once('SpecialPage.php');
 34+
 35+ define('MWRDF_VERSION', '0.7');
 36+ define('MWRDF_XML_TYPE_PREFS',
 37+ "application/rdf+xml,text/xml;q=0.7," .
 38+ "application/xml;q=0.5,text/rdf;q=0.1");
 39+ define('MWRDF_TURTLE_TYPE_PREFS',
 40+ "application/x-turtle,application/turtle;q=0.5,text/plain;q=0.1");
 41+ define('MWRDF_NTRIPLES_TYPE_PREFS',
 42+ "text/plain");
 43+
 44+ # Creative Commons namespace
 45+
 46+ define('CC_NS', "http://web.resource.org/cc/");
 47+ $CC_name = array('Work', 'Agent', 'License', 'Permission',
 48+ 'Requirement', 'Prohibition', 'PublicDomain',
 49+ 'Reproduction', 'Distribution', 'DerivativeWorks',
 50+ 'Notice', 'Attribution', 'ShareAlike', 'SourceCode',
 51+ 'CommercialUse', 'license', 'permits', 'requires',
 52+ 'prohibits', 'derivativeWork');
 53+
 54+ foreach ($CC_name as $name) {
 55+ $CC[$name] = new Resource(CC_NS . $name);
 56+ }
 57+
 58+ /* Config stuff -- set and reset in LocalSettings.php */
 59+
 60+ $wgRdfModelFunctions = array('inpage' => 'MwRdfInPage',
 61+ 'dcmes' => 'MwRdfDcmes',
 62+ 'cc' => 'MwRdfCreativeCommons',
 63+ 'linksto' => 'MwRdfLinksTo',
 64+ 'linksfrom' => 'MwRdfLinksFrom',
 65+ 'links' => 'MwRdfAllLinks',
 66+ 'image' => 'MwRdfImage',
 67+ 'history' => 'MwRdfHistory',
 68+ 'interwiki' => 'MwRdfInterwiki',
 69+ 'categories' => 'MwRdfCategories');
 70+
 71+ $wgRdfDefaultModels = array('inpage', 'cc', 'links', 'image', 'interwiki', 'categories');
 72+
 73+ $wgRdfOutputFunctions = array('xml' => 'MwRdfOutputXml',
 74+ 'turtle' => 'MwRdfOutputTurtle',
 75+ 'ntriples' => 'MwRdfOutputNtriples');
 76+
 77+ $wgRdfNamespaces = array('cc' => CC_NS);
 78+ $wgRdfCacheExpiry = 86400;
 79+
 80+ /* Config end */
 81+
 82+ $wgExtensionCredits['other'][] = array(
 83+ 'path' => __FILE__,
 84+ 'name' => 'RDF',
 85+ 'version' => MWRDF_VERSION,
 86+ 'description' => 'RDF framework for MediaWiki',
 87+ 'author' => 'Evan Prodromou',
 88+ 'url' => 'http://www.mediawiki.org/wiki/Extension:RDF',
 89+ );
 90+
 91+ $wgExtensionFunctions[] = 'setupMwRdf';
 92+
 93+ function setupMwRdf() {
 94+ global $wgParser, $wgMessageCache, $wgRequest, $wgOut, $wgHooks;
 95+
 96+ $wgMessageCache->addMessages(array('rdf' => 'Rdf',
 97+ 'rdf-inpage' => "Embedded In-page Turtle",
 98+ 'rdf-dcmes' => "Dublin Core Metadata Element Set",
 99+ 'rdf-cc' => "Creative Commons",
 100+ 'rdf-image' => "Embedded images",
 101+ 'rdf-linksto' => "Links to the page",
 102+ 'rdf-linksfrom' => "Links from the page",
 103+ 'rdf-links' => "All links",
 104+ 'rdf-history' => "Historical versions",
 105+ 'rdf-interwiki' => "Interwiki links",
 106+ 'rdf-categories' => "Categories",
 107+ 'rdf-target' => "Target page",
 108+ 'rdf-modelnames' => "Model(s)",
 109+ 'rdf-format' => "Output format",
 110+ 'rdf-output-xml' => "XML",
 111+ 'rdf-output-turtle' => "Turtle",
 112+ 'rdf-output-ntriples' => "NTriples",
 113+ 'rdf-instructions' => "Select the target page and RDF models you're interested in."));;
 114+
 115+ $wgParser->setHook( 'rdf', 'renderMwRdf' );
 116+ SpecialPage::AddPage(new SpecialPage('Rdf', '', true, 'wfSpecialRdf',
 117+ 'extensions/MwRdf.php'));
 118+
 119+ # Add an RDF metadata link if requested
 120+
 121+ $action = $wgRequest->getText('action', 'view');
 122+
 123+ # Note: $wgTitle not yet set; have to get it from the request
 124+
 125+ $title = $wgRequest->getText('title');
 126+
 127+ # If there's no requested title...
 128+
 129+ if (!isset($title) || strlen($title) == 0) {
 130+ # If there's no title, and Cache404 is in use, check using its stuff
 131+ if (defined('CACHE404_VERSION')) {
 132+ if ($_SERVER['REDIRECT_STATUS'] == 404) {
 133+ $url = getRedirectUrl($_SERVER);
 134+ if (isset($url)) {
 135+ $title = cacheUrlToTitle($url);
 136+ }
 137+ }
 138+ }
 139+ }
 140+
 141+ if (isset($title) && strlen($title) > 0) {
 142+ $nt = Title::newFromText($title);
 143+
 144+ if (isset($nt) &&
 145+ $nt->getNamespace() != NS_SPECIAL)
 146+ {
 147+ if ($action == 'view') {
 148+ $rdft = Title::makeTitle(NS_SPECIAL, "Rdf");
 149+ $target = $nt->getPrefixedDBkey();
 150+ $linkdata = array('title' => 'RDF Metadata',
 151+ 'type' => 'application/rdf+xml',
 152+ 'href' => $rdft->getLocalURL("target={$target}" ));
 153+ $wgOut->addMetadataLink($linkdata);
 154+ } else if ($action == 'purge') {
 155+ # clear cache on purge
 156+ MwRdfClearCacheAll($nt);
 157+ }
 158+ }
 159+ }
 160+
 161+ # We set some hooks for invalidating the cache
 162+
 163+ $wgHooks['ArticleSave'][] = 'MwRdfOnArticleSave';
 164+ $wgHooks['ArticleSaveComplete'][] = 'MwRdfOnArticleSaveComplete';
 165+ $wgHooks['TitleMoveComplete'][] = 'MwRdfOnTitleMoveComplete';
 166+ $wgHooks['ArticleDeleteComplete'][] = 'MwRdfOnArticleDeleteComplete';
 167+ }
 168+
 169+ function wfSpecialRdf($par) {
 170+ global $wgRequest, $wgRdfDefaultModels, $wgRdfOutputFunctions;
 171+
 172+ $target = $wgRequest->getVal('target');
 173+
 174+ if (!isset($target)) { # no target parameter
 175+ MwRdfShowForm();
 176+ } else if (strlen($target) == 0) { # no target contents
 177+ MwRdfShowForm(wfMsg('badtitle'));
 178+ } else {
 179+ $nt = Title::newFromText($target);
 180+ if ($nt->getArticleID() == 0) { # not an article
 181+ MwRdfShowForm(wfMsg('badtitle'));
 182+ } else {
 183+ $article = new Article($nt);
 184+
 185+ # Note: WebRequest chokes on arrays here
 186+ $modelnames = $_REQUEST['modelnames'];
 187+ if (is_null($modelnames)) {
 188+ $modelnames = $wgRdfDefaultModels;
 189+ }
 190+
 191+ if (is_string($modelnames)) {
 192+ $modelnames = explode(',', $modelnames);
 193+ }
 194+
 195+ $format = $wgRequest->getVal('format', 'xml');
 196+
 197+ $outfun = $wgRdfOutputFunctions[$format];
 198+
 199+ if (!isset($outfun)) {
 200+ wfDebugDieBacktrace("No output function for format '$format'.");
 201+ }
 202+
 203+ $fullModel = MwRdfGetModel($article, $modelnames);
 204+
 205+ $outfun($fullModel);
 206+ }
 207+ }
 208+ }
 209+
 210+ function MwRdfOutputXml($model) {
 211+
 212+ global $wgOut, $_SERVER, $wgRdfNamespaces;
 213+
 214+ $rdftype = wfNegotiateType(wfAcceptToPrefs($_SERVER['HTTP_ACCEPT']),
 215+ wfAcceptToPrefs(MWRDF_XML_TYPE_PREFS));
 216+
 217+ if (!$rdftype) {
 218+ wfHttpError(406, "Not Acceptable", wfMsg("notacceptable"));
 219+ return false;
 220+ } else {
 221+
 222+ $wgOut->disable();
 223+ header( "Content-type: {$rdftype}; charset=utf-8" );
 224+ $wgOut->sendCacheControl();
 225+
 226+ # Make sure serializer is loaded
 227+ require_once(RDFAPI_INCLUDE_DIR . PACKAGE_SYNTAX_RDF);
 228+
 229+ $ser = new RDFSerializer();
 230+
 231+ $ser->configSortModel(true);
 232+ $ser->configUseAttributes(false);
 233+ $ser->configUseEntities(false);
 234+
 235+ foreach($wgRdfNamespaces as $key => $value) {
 236+ $ser->addNamespacePrefix($key,$value);
 237+ }
 238+
 239+ print($ser->serialize($model));
 240+
 241+ return true;
 242+ }
 243+ }
 244+
 245+ function MwRdfOutputNtriples($model) {
 246+
 247+ global $wgOut, $_SERVER, $wgRdfNamespaces;
 248+
 249+ $rdftype = wfNegotiateType(wfAcceptToPrefs($_SERVER['HTTP_ACCEPT']),
 250+ wfAcceptToPrefs(MWRDF_NTRIPLES_TYPE_PREFS));
 251+
 252+ if (!$rdftype) {
 253+ wfHttpError(406, "Not Acceptable", wfMsg("notacceptable"));
 254+ return false;
 255+ } else {
 256+
 257+ $wgOut->disable();
 258+ header( "Content-type: {$rdftype}; charset=utf-8" );
 259+ $wgOut->sendCacheControl();
 260+
 261+ # Make sure serializer is loaded
 262+ require_once(RDFAPI_INCLUDE_DIR . PACKAGE_SYNTAX_RDF);
 263+
 264+ $ser = new NTripleSerializer();
 265+
 266+ print($ser->serialize($model));
 267+
 268+ return true;
 269+ }
 270+ }
 271+
 272+ function MwRdfOutputTurtle($model) {
 273+
 274+ global $wgOut, $_SERVER, $wgRdfNamespaces;
 275+
 276+ $rdftype = wfNegotiateType(wfAcceptToPrefs($_SERVER['HTTP_ACCEPT']),
 277+ wfAcceptToPrefs(MWRDF_TYPE_PREFS));
 278+
 279+ if (!$rdftype) {
 280+ wfHttpError(406, "Not Acceptable", wfMsg("notacceptable"));
 281+ return false;
 282+ } else {
 283+
 284+ $wgOut->disable();
 285+ header( "Content-type: {$rdftype}; charset=utf-8" );
 286+ $wgOut->sendCacheControl();
 287+
 288+ # Make sure serializer is loaded
 289+ require_once(RDFAPI_INCLUDE_DIR . PACKAGE_SYNTAX_N3);
 290+
 291+ $ser = new N3Serializer();
 292+
 293+ foreach($wgRdfNamespaces as $key => $value) {
 294+ $ser->addNSPrefix($key,$value);
 295+ }
 296+
 297+ print($ser->serialize($model));
 298+
 299+ return true;
 300+ }
 301+ }
 302+
 303+ function MwRdfGetModel($article, $modelnames = null) {
 304+
 305+ global $wgRdfModelFunctions, $wgRdfDefaultModels;
 306+
 307+ if ($modelnames == null) {
 308+ $modelnames = $wgRdfDefaultModels;
 309+ }
 310+
 311+ $fullModel = ModelFactory::getDefaultModel();
 312+ $title = $article->mTitle;
 313+
 314+ $uri = $title->getFullURL();
 315+ $fullModel->setBaseURI($uri);
 316+
 317+ foreach ($modelnames as $modelname) {
 318+ $modelfunc = $wgRdfModelFunctions[$modelname];
 319+ if (!$modelfunc) {
 320+ wfDebugDieBacktrace("MwRdf: No RDF model named '$modelname'.");
 321+ } elseif (!function_exists($modelfunc)) {
 322+ wfDebugDieBacktrace("MwRdf: No function named '$modelfunc' " .
 323+ " for model '$modelname'.");
 324+ }
 325+
 326+ # Check the cache...
 327+
 328+ $model = MwRdfGetCache($title, $modelname);
 329+
 330+ # If it's not there, regenerate.
 331+
 332+ if (!isset($model) || !$model) {
 333+ $model = $modelfunc($article);
 334+ MwRdfSetCache($title, $modelname, $model);
 335+ }
 336+
 337+ if (isset($model)) {
 338+ $fullModel->addModel($model);
 339+ }
 340+ }
 341+
 342+ return $fullModel;
 343+ }
 344+
 345+ function MwRdfShowForm($msg = null) {
 346+ global $wgOut, $wgRdfModelFunctions, $wgRdfOutputFunctions, $wgRdfDefaultModels, $wgUser;
 347+ $sk = $wgUser->getSkin();
 348+ $instructions = $wgOut->parse(wfMsg('rdf-instructions'));
 349+ if (isset($msg) && strlen($msg) > 0) {
 350+ $wgOut->addHTML("<p class='error'>${msg}</p>");
 351+ }
 352+ $wgOut->addHTML("<p>{$instructions}</p>" .
 353+ "<form action='" . $sk->makeSpecialUrl('Rdf') . "' method='POST'>" .
 354+ "<table border='0'>" .
 355+ "<tr>" .
 356+ "<td align='right'><label for='target'>" . wfMsg('rdf-target') . "</label></td>" .
 357+ "<td align='left'><input type='text' size='30' name='target' id='target' /></td> " .
 358+ "</tr>" .
 359+ "<tr>" .
 360+ "<td align='right'><label for='modelnames[]'>" . wfMsg('rdf-modelnames') . "</label></td>" .
 361+ "<td align='left'><select name='modelnames[]' multiple='multiple' size='6'>");
 362+ foreach (array_keys($wgRdfModelFunctions) as $modelname) {
 363+ $selectedpart = in_array($modelname, $wgRdfDefaultModels) ? "selected='selected'" : "";
 364+ $wgOut->addHTML("<option value='{$modelname}' {$selectedpart}>" . wfMsg('rdf-' . $modelname) . "</option>");
 365+ }
 366+ $wgOut->addHTML("</select></td></tr>" .
 367+ "<tr> " .
 368+ "<td align='right'><label for='format'>" . wfMsg('rdf-format') . "</label></td>" .
 369+ "<td align='left'><select name='format'>");
 370+ foreach (array_keys($wgRdfOutputFunctions) as $outputname) {
 371+ $wgOut->addHTML("<option value=${outputname}>" . wfMsg('rdf-output-' . $outputname) . "</option>");
 372+ }
 373+ $wgOut->addHTML("</select></td></tr>" .
 374+ "<tr><td>&nbsp;</td>" .
 375+ "<td><input type='submit' /></td></tr></table></form>");
 376+ }
 377+
 378+ function MwRdfInPage($article) {
 379+ $text = $article->getContent(true);
 380+ $parser = new Parser();
 381+ $text = $parser->preprocess($text, $article->mTitle, new ParserOptions());
 382+
 383+ preg_match_all("@<rdf>(.*?)</rdf>@s", $text, $matches, PREG_PATTERN_ORDER);
 384+ $content = $matches[1];
 385+ $rdf = implode(' ', array_values($content));
 386+
 387+ $model = null;
 388+
 389+ if (strlen($rdf) > 0) {
 390+
 391+ $parser->mOutputType = OT_HTML;
 392+ $rdf = $parser->replaceVariables($rdf);
 393+
 394+ global $default_prefixes, $wgRdfNamespaces;
 395+ require_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
 396+
 397+ $parser = new N3Parser();
 398+ $parser->baseURI = $article->mTitle->getFullURL();
 399+
 400+ $prefixes = array_merge($default_prefixes, $wgRdfNamespaces, MwRdfNamespacePrefixes());
 401+
 402+ $prelude = "";
 403+
 404+ foreach ($prefixes as $prefix => $uri) {
 405+ $prelude .= "@prefix $prefix: <$uri> .\n";
 406+ }
 407+
 408+ # XXX: set correct properties
 409+ $model = $parser->parse2model($prelude . $rdf);
 410+ if ($model === false) {
 411+ global $RDFS_comment;
 412+ $model = ModelFactory::getDefaultModel();
 413+ $model->add(new Statement(MwRdfArticleResource($article),
 414+ $RDFS_comment,
 415+ MwRdfLiteral("Error parsing in-page RDF: "
 416+ . $parser->errors[0] .
 417+ "\n code here: \n '" . $prelude . $rdf . "'" , null,
 418+ "en")));
 419+ } else {
 420+ # To make it unique, we unite with an empty model
 421+ $fake = new MemModel();
 422+ $model =& $fake->unite($model);
 423+ }
 424+ }
 425+ return $model;
 426+ }
 427+
 428+ function MwRdfDcmes($article) {
 429+
 430+ global $wgContLanguageCode, $wgSitename, $DCMES, $DCMITYPE;
 431+
 432+ $model = ModelFactory::getDefaultModel();
 433+
 434+ $nt = $article->mTitle;
 435+ $artres = MwRdfArticleResource($article);
 436+
 437+ $model->add(new Statement($artres, $DCMES['title'],
 438+ MwRdfLiteral($article->mTitle->getText(),
 439+ null, $wgContLanguageCode)));
 440+ $model->add(new Statement($artres, $DCMES['publisher'],
 441+ MwRdfPageOrString(wfMsg('aboutpage'),
 442+ $wgSitename)));
 443+ $model->add(new Statement($artres, $DCMES['language'],
 444+ MwRdfLanguage($wgContLanguageCode)));
 445+ $model->add(new Statement($artres, $DCMES['type'],
 446+ $DCMITYPE['Text']));
 447+ $model->add(new Statement($artres, $DCMES['format'],
 448+ MwRdfMediaType('text/html')));
 449+
 450+ $model->add(new Statement($artres, $DCMES['date'],
 451+ MwRdfTimestamp($article->getTimestamp())));
 452+
 453+ if ( MWNamespace::isTalk( $nt->getNamespace() ) ) {
 454+ $model->add(new Statement($artres, $DCMES['subject'],
 455+ MwRdfTitleResource($nt->getSubjectPage())));
 456+ } else {
 457+ $model->add(new Statement(MwRdfTitleResource($nt->getTalkPage()),
 458+ $DCMES['subject'], $artres));
 459+ }
 460+
 461+ # 'Creator' is responsible for this version
 462+
 463+ $last_editor = $article->getUser();
 464+
 465+ $creator = ($last_editor == 0) ?
 466+ MwRdfPersonResource(0) :
 467+ MwRdfPersonResource($last_editor, $article->getUserText(),
 468+ User::whoIsReal($last_editor));
 469+
 470+ $model->add(new Statement($artres, $DCMES['creator'],
 471+ $creator));
 472+
 473+ # 'Contributors' are all other version authors
 474+
 475+ $contributors = $article->getContributors();
 476+
 477+ foreach ($contributors as $user_parts) {
 478+ $contributor = MwRdfPersonResource($user_parts[0],
 479+ $user_parts[1],
 480+ $user_parts[2]);
 481+ $model->add(new Statement($artres, $DCMES['contributor'],
 482+ $contributor));
 483+ }
 484+
 485+ # Rights notification
 486+
 487+ global $wgRightsPage, $wgRightsUrl, $wgRightsText;
 488+
 489+ $rights = (isset($wgRightsPage) &&
 490+ ($nt = Title::newFromText($wgRightsPage))
 491+ && ($nt->getArticleID() != 0)) ?
 492+ MwRdfTitleResource($nt) :
 493+ (isset($wgRightsUrl)) ?
 494+ MwRdfGetResource($wgRightsUrl) :
 495+ (isset($wgRightsText)) ?
 496+ new Literal($wgRightsText) : null;
 497+
 498+ if ($rights != null) {
 499+ $model->add(new Statement($artres, $DCMES['rights'], $rights));
 500+ }
 501+
 502+ return $model;
 503+ }
 504+
 505+ function MwRdfCreativeCommons($article) {
 506+ global $RDF_type, $CC, $wgRightsUrl;
 507+
 508+ $ar = MwRdfArticleResource($article);
 509+ $model = MwRdfDcmes($article);
 510+ $model->add(new Statement($ar, $RDF_type, $CC['Work']));
 511+
 512+ if (isset($wgRightsUrl)) {
 513+ $lr = MwRdfGetResource($wgRightsUrl);
 514+ $model->add(new Statement($ar, $CC['license'], $lr));
 515+ $model->add(new Statement($lr, $RDF_type, $CC['License']));
 516+ $terms = MwRdfGetCcTerms($wgRightsUrl);
 517+ if (isset($terms)) {
 518+ foreach ($terms as $term) {
 519+ switch ($term) {
 520+ case 're':
 521+ $model->add(new Statement($lr, $CC['permits'],
 522+ $CC['Reproduction']));
 523+ break;
 524+ case 'di':
 525+ $model->add(new Statement($lr, $CC['permits'],
 526+ $CC['Distribution']));
 527+ break;
 528+ case 'de':
 529+ $model->add(new Statement($lr, $CC['permits'],
 530+ $CC['DerivativeWorks']));
 531+ break;
 532+ case 'nc':
 533+ $model->add(new Statement($lr, $CC['prohibits'],
 534+ $CC['CommercialUse']));
 535+ break;
 536+ case 'no':
 537+ $model->add(new Statement($lr, $CC['requires'],
 538+ $CC['Notice']));
 539+ break;
 540+ case 'by':
 541+ $model->add(new Statement($lr, $CC['requires'],
 542+ $CC['Attribution']));
 543+ break;
 544+ case 'sa':
 545+ $model->add(new Statement($lr, $CC['requires'],
 546+ $CC['ShareAlike']));
 547+ break;
 548+ case 'sc':
 549+ $model->add(new Statement($lr, $CC['requires'],
 550+ $CC['SourceCode']));
 551+ break;
 552+ }
 553+ }
 554+ }
 555+ }
 556+
 557+ return $model;
 558+ }
 559+
 560+ function MwRdfLinksTo($article) {
 561+ global $DCTERM;
 562+ $model = ModelFactory::getDefaultModel();
 563+ $nt = $article->getTitle();
 564+ $tr = MwRdfTitleResource($nt);
 565+ $linksto = $nt->getLinksTo();
 566+ foreach ($linksto as $linkto) {
 567+ $lr = MwRdfTitleResource($linkto);
 568+ $model->add(new Statement($tr, $DCTERM['isReferencedBy'], $lr));
 569+ }
 570+ return $model;
 571+ }
 572+
 573+ function MwRdfLinksFrom($article) {
 574+ global $DCTERM;
 575+ $model = ModelFactory::getDefaultModel();
 576+ $ar = MwRdfArticleResource($article);
 577+ $dbr = wfGetDB(DB_SLAVE);
 578+ $res = $dbr->select(array('pagelinks'),
 579+ array('pl_namespace', 'pl_title'),
 580+ array('pl_from = ' . $article->mTitle->getArticleID()),
 581+ 'MwRdfLinksFrom',
 582+ array('ORDER BY' => 'pl_namespace, pl_title'));
 583+ while ($res && $row = $dbr->fetchObject($res)) {
 584+ $lt = Title::makeTitle($row->pl_namespace, $row->pl_title);
 585+ $model->add(new Statement($ar, $DCTERM['references'],
 586+ MwRdfTitleResource($lt)));
 587+ }
 588+ $dbr->freeResult($res);
 589+ return $model;
 590+ }
 591+
 592+ function MwRdfAllLinks($article) {
 593+ $model = ModelFactory::getDefaultModel();
 594+ $model->addModel(MwRdfLinksTo($article));
 595+ $model->addModel(MwRdfLinksFrom($article));
 596+
 597+ return $model;
 598+ }
 599+
 600+ function MwRdfHistory($article) {
 601+ global $DCTERM, $DCMES, $wgContLanguageCode;
 602+
 603+ $model = ModelFactory::getDefaultModel();
 604+ $nt = $article->getTitle();
 605+ $tr = MwRdfTitleResource($nt);
 606+ $dbr = wfGetDB( DB_SLAVE );
 607+ $res = $dbr->select( array('page', 'revision'),
 608+ array('rev_id', 'rev_timestamp', 'rev_user', 'rev_user_text'),
 609+ array('page_namespace = ' . $nt->getNamespace(),
 610+ 'page_title = ' . $dbr->addQuotes($nt->getDBkey()),
 611+ 'rev_page = page_id',
 612+ 'rev_id != page_latest'),
 613+ 'MwRdfHistory',
 614+ array('ORDER BY' => 'rev_timestamp DESC'));
 615+ while ($res && $row = $dbr->fetchObject($res)) {
 616+ $url = $nt->getFullURL('oldid=' . $row->rev_id);
 617+ $ur = MwRdfGetResource($url);
 618+ $model->add(new Statement($tr, $DCTERM['hasVersion'], $ur));
 619+ $model->add(new Statement($ur, $DCTERM['isVersionOf'], $tr));
 620+ $model->add(new Statement($ur, $DCMES['language'], MwRdfLanguage($wgContLanguageCode)));
 621+ $pr = MwRdfPersonResource($row->rev_user, $row->rev_user_text,
 622+ ($row->rev_user == 0) ? null : User::whoIsReal($row->rev_user));
 623+ $model->add(new Statement($ur, $DCMES['creator'], $pr));
 624+ $model->add(new Statement($ur, $DCMES['date'],
 625+ MwRdfTimestamp($row->rev_timestamp)));
 626+ }
 627+ $dbr->freeResult($res);
 628+ return $model;
 629+ }
 630+
 631+ function MwRdfImage($article) {
 632+ global $DCTERM, $DCMES, $DCMITYPE, $wgServer;
 633+
 634+ static $typecode = array( 1 => 'image/gif', 2 => 'image/jpeg',
 635+ 3 => 'image/png' );
 636+
 637+ $model = ModelFactory::getDefaultModel();
 638+
 639+ $nt = $article->getTitle();
 640+ $tr = MwRdfTitleResource($nt);
 641+
 642+ $dbr = wfGetDB( DB_SLAVE );
 643+ $res = $dbr->select('imagelinks',
 644+ array('il_to'),
 645+ array('il_from = ' . $nt->getArticleID()),
 646+ 'MwRdfImage');
 647+
 648+ while ($res && $row = $dbr->fetchObject($res)) {
 649+ $img = wfFindFile($row->il_to);
 650+ if ($img->exists()) {
 651+ $iuri = $img->getURL();
 652+ if ($iuri[0] == '/') {
 653+ $iuri = $wgServer . $iuri;
 654+ }
 655+ $ir = MwRdfGetResource($iuri);
 656+ $model->add(new Statement($tr, $DCTERM['hasPart'], $ir));
 657+ $model->add(new Statement($ir, $DCMES['type'], $DCMITYPE['Image']));
 658+ $tc = $img->getMimeType();
 659+ $mt = $typecode[$tc];
 660+ if (isset($mt)) {
 661+ $model->add(new Statement($ir, $DCMES['format'],
 662+ MwRdfMediaType($mt)));
 663+ }
 664+ $hl = $img->nextHistoryLine();
 665+ if ($hl) {
 666+ $creator = MwRdfPersonResource($hl->img_user, $hl->img_user_text,
 667+ User::whoIsReal($hl->img_user));
 668+ $model->add(new Statement($ir, $DCMES['creator'], $creator));
 669+ $model->add(new Statement($ir, $DCMES['date'],
 670+ MwRdfTimestamp($hl->img_timestamp)));
 671+ $seen = array($hl->img_user => true);
 672+ while ($hl = $img->nextHistoryLine()) {
 673+ if (!isset($seen[$hl->img_user])) {
 674+ $contributor = MwRdfPersonResource($hl->img_user, $hl->img_user_text,
 675+ User::whoIsReal($hl->img_user));
 676+ $model->add(new Statement($ir, $DCMES['contributor'], $contributor));
 677+ $seen[$hl->img_user] = true;
 678+ }
 679+ }
 680+ }
 681+ }
 682+ }
 683+
 684+ $dbr->freeResult($res);
 685+ return $model;
 686+ }
 687+
 688+ function MwRdfInterwiki($article) {
 689+ global $DCTERM, $DCMES, $DCMITYPE, $RDFS_seeAlso, $wgContLang;
 690+
 691+ $model = ModelFactory::getDefaultModel();
 692+
 693+ $nt = $article->getTitle();
 694+ $tr = MwRdfTitleResource($nt);
 695+ $text = $article->getContent(true);
 696+
 697+ $parser = new Parser();
 698+
 699+ $text = $parser->preprocess($text, $article->mTitle, new ParserOptions());
 700+ # XXX: this sucks
 701+ # Ignore <nowiki> blocks
 702+ $text = preg_replace("|(<nowiki>.*</nowiki>)|", "", $text);
 703+
 704+ # Find prefixed links
 705+ preg_match_all("/\[\[([^|\]]+:[^|\]]+)(\|.*)?\]\]/", $text, $matches);
 706+
 707+ # XXX: this fails for Category: namespace; why?
 708+
 709+ if (isset($matches)) {
 710+ foreach ($matches[1] as $linktext) {
 711+ $iwlink = Title::newFromText($linktext);
 712+ if (isset($iwlink)) {
 713+ $pfx = $iwlink->getInterwiki();
 714+ if (strlen($pfx) > 0) {
 715+ $iwr = MwRdfTitleResource($iwlink);
 716+ # XXX: Wikitravel uses some 4+ prefixes for sister site links
 717+ if ($wgContLang->getLanguageName($pfx) && strlen($pfx) < 4) {
 718+ $model->add(new Statement($tr, $DCTERM['hasVersion'], $iwr));
 719+ $model->add(new Statement($iwr, $DCMES['language'],
 720+ MwRdfLanguage($pfx)));
 721+ } else {
 722+ # XXX: Express the "sister site" relationship better
 723+ $model->add(new Statement($tr, $RDFS_seeAlso,
 724+ $iwr));
 725+ }
 726+ }
 727+ }
 728+ }
 729+ }
 730+
 731+ return $model;
 732+ }
 733+
 734+ function MwRdfCategories($article) {
 735+ global $DCMES;
 736+
 737+ $model = ModelFactory::getDefaultModel();
 738+ $nt = $article->mTitle;
 739+ $ar = MwRdfTitleResource($nt);
 740+ $categories = $nt->getParentCategories();
 741+
 742+ if (is_array($categories)) {
 743+ foreach (array_keys($categories) as $category) {
 744+ $cattitle = Title::newFromText($category);
 745+ $model->add(new Statement($ar, $DCMES['subject'],
 746+ MwRdfTitleResource($cattitle)));
 747+ }
 748+ }
 749+
 750+ return $model;
 751+ }
 752+
 753+ # Utility functions
 754+
 755+ # A dummy rendering procedure for the <rdf> ... </rdf> block used for in-page RDF
 756+
 757+ function renderMwRdf($input, $argv = null, $parser = null) {
 758+ return ' ';
 759+ }
 760+
 761+ function MwRdfGetResource($url) {
 762+ static $_MwRdfResourceCache = array();
 763+
 764+ if ($_MwRdfResourceCache[$url]) {
 765+ return $_MwRdfResourceCache[$url];
 766+ } else {
 767+ $res = new Resource($url);
 768+ $_MwRdfResourceCache[$url] = $res;
 769+ return $res;
 770+ }
 771+ }
 772+
 773+ function MwRdfArticleResource($article) {
 774+ $title = $article->getTitle();
 775+ return MwRdfTitleResource($title);
 776+ }
 777+
 778+ function MwRdfTitleResource($title) {
 779+ return MwRdfGetResource($title->getFullURL());
 780+ }
 781+
 782+ function MwRdfPersonResource($id, $user_name='', $user_real_name='') {
 783+ global $wgContLang;
 784+
 785+ if ($id == 0) {
 786+ return new Literal(wfMsg('anonymous'));
 787+ } else if ( !empty($user_real_name) ) {
 788+ return new Literal($user_real_name);
 789+ } else {
 790+ # XXX: This shouldn't happen.
 791+ if( empty( $user_name ) ) {
 792+ $user_name = User::whoIs($id);
 793+ }
 794+ return MwRdfPageOrString($wgContLang->getNsText(NS_USER) . ':' . $user_name,
 795+ wfMsg('siteuser', $user_name));
 796+ }
 797+ }
 798+
 799+ function MwRdfPageOrString($page, $str) {
 800+ $nt = Title::newFromText($page);
 801+
 802+ if (!$nt || $nt->getArticleID() == 0) {
 803+ return MwRdfLiteral($str);
 804+ } else {
 805+ return MwRdfTitleResource($nt);
 806+ }
 807+ }
 808+
 809+ function MwRdfGetCcTerms($url) {
 810+ static $knownLicenses;
 811+
 812+ if (!isset($knownLicenses)) {
 813+ $knownLicenses = array();
 814+ $ccLicenses = array('by', 'by-nd', 'by-nd-nc', 'by-nc',
 815+ 'by-nc-sa', 'by-sa', 'nd', 'nd-nc',
 816+ 'nc', 'nc-sa', 'sa');
 817+ $ccVersions = array('1.0', '2.0', '2.5');
 818+
 819+ foreach ($ccVersions as $version) {
 820+ foreach ($ccLicenses as $license) {
 821+ if( $version != '1.0' && substr($license, 0, 2) != 'by' ) {
 822+ # 2.0 dropped the non-attribs licenses
 823+ continue;
 824+ }
 825+ $lurl = "http://creativecommons.org/licenses/{$license}/{$version}/";
 826+ $knownLicenses[$lurl] = explode('-', $license);
 827+ $knownLicenses[$lurl][] = 're';
 828+ $knownLicenses[$lurl][] = 'di';
 829+ $knownLicenses[$lurl][] = 'no';
 830+ if (!in_array('nd', $knownLicenses[$lurl])) {
 831+ $knownLicenses[$lurl][] = 'de';
 832+ }
 833+ }
 834+ }
 835+
 836+ /* Handle the GPL and LGPL, too. */
 837+
 838+ $knownLicenses['http://creativecommons.org/licenses/GPL/2.0/'] =
 839+ array('de', 're', 'di', 'no', 'sa', 'sc');
 840+ $knownLicenses['http://creativecommons.org/licenses/LGPL/2.1/'] =
 841+ array('de', 're', 'di', 'no', 'sa', 'sc');
 842+ $knownLicenses['http://www.gnu.org/copyleft/fdl.html'] =
 843+ array('de', 're', 'di', 'no', 'sa', 'sc');
 844+ }
 845+
 846+ return $knownLicenses[$url];
 847+ }
 848+
 849+ function MwRdfLiteral($str, $type = null, $lang = null) {
 850+ static $cache = array();
 851+ if (isset($cache["$type:$lang:$str"])) {
 852+ return $cache["$type:$lang:$str"];
 853+ } else {
 854+ if (isset($lang)) {
 855+ $lit = new Literal($str, $lang);
 856+ } else {
 857+ $lit = new Literal($str);
 858+ }
 859+
 860+ if (isset($type)) {
 861+ $lit->setDatatype($type);
 862+ }
 863+ $cache["$type:$lang:$str"] = $lit;
 864+ return $lit;
 865+ }
 866+ }
 867+
 868+ function MwRdfMediaType($str) {
 869+ return MwRdfLiteral($str, DC_NS . 'IMT');
 870+ }
 871+
 872+ function MwRdfLanguage($code) {
 873+ return MwRdfLiteral($code, DC_NS . 'ISO639-2');
 874+ }
 875+
 876+ function MwRdfTimestamp($timestamp) {
 877+ $dt = wfTimestamp(TS_DB, $timestamp);
 878+ # 'YYYY-MM-DD HH:MI:SS' => 'YYYY-MM-DDTHH:MI:SSZ'
 879+ $dt = str_replace(" ", "T", $dt) . "Z";
 880+ return MwRdfLiteral($dt, DC_NS . W3CDTF);
 881+ }
 882+
 883+ # Returns an array of prefixes for all namespaces
 884+
 885+ function MwRdfNamespacePrefixes() {
 886+ static $prefixes;
 887+
 888+ if (!isset($prefixes)) {
 889+ global $wgLang; # all working namespaces
 890+ $prefixes = array();
 891+ $spaces = $wgLang->getNamespaces();
 892+ foreach ($spaces as $code => $text) {
 893+ $prefix = urlencode(str_replace(' ', '_', $text));
 894+ # FIXME: this is a hack
 895+ if (strpos($prefix, '%') === false) {
 896+ # XXX: figure out a less sneaky way to do this
 897+ # XXX: won't work if article title isn't at the end of the URL
 898+ $title = Title::makeTitle($code, '');
 899+ $uri = $title->getFullURL();
 900+ $prefixes[$prefix] = $uri;
 901+ }
 902+ }
 903+ }
 904+ return $prefixes;
 905+ }
 906+
 907+ function MwRdfGetCache($title, $modelname) {
 908+ global $wgMemc;
 909+ if (!isset($wgMemc)) {
 910+ return false;
 911+ } else {
 912+ $ntrip = $wgMemc->get(MwRdfCacheKey($title, $modelname));
 913+ if (isset($ntrip) && $ntrip && strlen($ntrip) > 0) {
 914+ return MwRdfNTriplesToModel($ntrip);
 915+ } else {
 916+ return null;
 917+ }
 918+ }
 919+ }
 920+
 921+ function MwRdfClearCache($title, $modelname) {
 922+ global $wgMemc;
 923+ if (!isset($wgMemc)) {
 924+ return false;
 925+ } else {
 926+ return $wgMemc->delete(MwRdfCacheKey($title, $modelname));
 927+ }
 928+ }
 929+
 930+ function MwRdfClearCacheAll($title) {
 931+ global $wgRdfModelFunctions;
 932+ $nt = $title;
 933+ foreach (array_keys($wgRdfModelFunctions) as $modelname) {
 934+ MwRdfClearCache($nt, $modelname);
 935+ }
 936+ }
 937+
 938+ function MwRdfSetCache($title, $modelname, $model) {
 939+ global $wgMemc, $wgRdfCacheExpiry;
 940+ if (!isset($wgMemc)) {
 941+ return false;
 942+ } else {
 943+ return $wgMemc->set(MwRdfCacheKey($title, $modelname),
 944+ MwRdfModelToNTriples($model),
 945+ $wgRdfCacheExpiry);
 946+ }
 947+ }
 948+
 949+ function MwRdfCacheKey($title, $modelname) {
 950+ if (!isset($title)) {
 951+ return null;
 952+ } else {
 953+ global $wgDBname;
 954+ $dbkey = $title->getDBkey();
 955+ $ns = $title->getNamespace();
 956+ return "$wgDBname:rdf:$ns:$dbkey:$modelname";
 957+ }
 958+ }
 959+
 960+ # Before saving, we clear the cache for articles this article links to
 961+
 962+ function MwRdfOnArticleSave($article, $dc1, $dc2, $dc3, $dc4, $dc5, $dc6) {
 963+ $id = $article->mTitle->getArticleID();
 964+ if ($id != 0) {
 965+ $dbr = wfGetDB(DB_SLAVE);
 966+ $res = $dbr->select('pagelinks',
 967+ array('pl_namespace', 'pl_title'),
 968+ array('pl_from = ' . $id),
 969+ 'MwRdfOnArticleSave');
 970+ while ($res && $row = $dbr->fetchObject($res)) {
 971+ $lt = Title::makeTitle($row->pl_namespace, $row->pl_title);
 972+ MwRdfClearCache($lt, 'linksto');
 973+ }
 974+ }
 975+ return true;
 976+ }
 977+
 978+ # Clear the cache when the article is saved
 979+
 980+ function MwRdfOnArticleSaveComplete($article, $dc1, $dc2, $dc3, $dc4, $dc5, $dc6) {
 981+ MwRdfClearCacheAll($article->mTitle);
 982+ return true;
 983+ }
 984+
 985+ # Clear the cache when an article is moved
 986+
 987+ function MwRdfOnTitleMoveComplete($oldt, $newt, $user, $oldid, $newid) {
 988+ MwRdfClearCacheAll($newt);
 989+ MwRdfClearCacheAll($oldt);
 990+ return true;
 991+ }
 992+
 993+ # Clear the cache when an article is deleted
 994+
 995+ function MwRdfOnArticleDeleteComplete($article, $user, $reason) {
 996+ MwRdfClearCacheAll($article->mTitle);
 997+ return true;
 998+ }
 999+
 1000+ function MwRdfNTriplesToModel($ntrip) {
 1001+ require_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
 1002+ $parser = new N3Parser();
 1003+ $model = $parser->parse2model($ntrip);
 1004+ return $model;
 1005+ }
 1006+
 1007+ function MwRdfModelToNTriples($model) {
 1008+ # Make sure serializer is loaded
 1009+ if (!isset($model) || $model->size() == 0) {
 1010+ return '';
 1011+ } else {
 1012+ require_once(RDFAPI_INCLUDE_DIR . PACKAGE_SYNTAX_N3);
 1013+ $ser = new NTripleSerializer();
 1014+ return $ser->serialize($model);
 1015+ }
 1016+ }
 1017+
 1018+ # This is used by a lot of RDF extensions, so put it here
 1019+
 1020+ function MwRdfFullUrlToTitle($url) {
 1021+ global $wgArticlePath, $wgServer;
 1022+ $parts = parse_url($url);
 1023+ $relative = $parts['path'];
 1024+ if (!is_null($parts['query']) && strlen($parts['query']) > 0) {
 1025+ $relative .= '?' . $parts['query'];
 1026+ }
 1027+ $pattern = str_replace('$1', '(.*)', $wgArticlePath);
 1028+ $pattern = str_replace('?', '\?', $pattern);
 1029+ # Can't have a pound-sign in the relative, since that's for fragments
 1030+ if (preg_match("#$pattern#", $relative, $matches)) {
 1031+ $titletext = urldecode($matches[1]);
 1032+ $nt = Title::newFromText($titletext);
 1033+ return $nt;
 1034+ } else {
 1035+ return null;
 1036+ }
 1037+ }
 1038+
 1039+}
 1040+
 1041+
Property changes on: trunk/extensions/Rdf/Rdf.php
___________________________________________________________________
Name: svn:keywords
11042 + Author Date Id Revision
Name: svn:eol-style
21043 + native
Index: trunk/extensions/Rdf/README.RDF.txt
@@ -0,0 +1,314 @@
 2+MediaWiki RDF extension
 3+
 4+version 0.7
 5+26 Nov 2006
 6+
 7+This is the README file for the RDF extension for MediaWiki
 8+software. The extension is only useful if you've got a MediaWiki
 9+installation; it can only be installed by the administrator of the site.
 10+
 11+The extension adds RDF (= Resource Definition Framework) support to
 12+MediaWiki. It will show RDF data about a page with a new special page,
 13+Special:Rdf. It allows users to add custom RDF statements to a page
 14+between <rdf> ... </rdf> tags. Administrators and programmers can add
 15+new automated RDF models, too.
 16+
 17+This is an early version of the extension and it's almost sure to
 18+have bugs. See the BUGS section below for info on how to report
 19+problems.
 20+
 21+== License ==
 22+
 23+Copyright 2005, 2006 Evan Prodromou <evan@wikitravel.org>.
 24+
 25+This program is free software; you can redistribute it and/or modify
 26+it under the terms of the GNU General Public License as published by
 27+the Free Software Foundation; either version 2 of the License, or
 28+(at your option) any later version.
 29+
 30+This program is distributed in the hope that it will be useful,
 31+but WITHOUT ANY WARRANTY; without even the implied warranty of
 32+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 33+GNU General Public License for more details.
 34+
 35+You should have received a copy of the GNU General Public License
 36+along with this program; if not, write to the Free Software
 37+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 38+
 39+== Installation ==
 40+
 41+You have to have MediaWiki 1.5.x installed for this software to work.
 42+Sorry, but that's the version I've got installed, so it's the one this
 43+software works with.
 44+
 45+You also have to install RAP, the RDF API for PHP
 46+(www.wiwiss.fu-berlin.de/suhl/bizer/rdfapi/) . I used version 0.92,
 47+plus some custom hacks to make the N3 parser less fragile. You have to
 48+apply a patch to the distribution if you want RDF to work; it's
 49+included in this distribution. (Future versions of RAP will have these
 50+enhancements).
 51+
 52+You should be able to move the directory created by unpacking the
 53+MwRDF archive to the extensions subdirectory of your MediaWiki
 54+installation. Then add these lines to your LocalSettings.php:
 55+
 56+ define("RDFAPI_INCLUDE_DIR", "/full/path/to/rdfapi-php/api/");
 57+ require_once("extensions/Rdf/Rdf.php");
 58+
 59+== 60-second intro to RDF ==
 60+
 61+RDF is a framework for making statements about resources. Statements
 62+are in the form:
 63+
 64+ subject predicate object
 65+
 66+Here, "subject" is a "resource" such as a person, place, idea, Web
 67+page, picture, concept, or whatever. "Predicates" are names of
 68+properties of a resource, like its color, shape, texture, size,
 69+history, or relationships to other "resources". The object is the
 70+value of the property. So "car color red" would be a statement about a
 71+car; "Evan hasBrother Nate" would be a statement about a person.
 72+
 73+Of course, it's important to be definite about which resources and
 74+which properties we're discussing. In the Web world, each "resource"
 75+is identified with a URI (usually an URL).
 76+
 77+For electronic resources, this is usually pretty easy; the main page
 78+of English-language Wikipedia, for example, has the URI
 79+"http://en.wikipedia.org/wiki/Main_Page". However, for analog subjects
 80+like people or ideas or physical objects, this can be a little
 81+trickier.
 82+
 83+There's no general solution, but the typical workaround is to use real
 84+or made-up URIs to "stand in" for offline entities. For example, you
 85+could use the URI for my Wikitravel user page,
 86+"http://wikitravel.org/en/User:Evan", as the URI for me. Or you could
 87+use my email address in URI form, like "mailto:evan@wikitravel.org".
 88+
 89+People who need to agree on statements often create 'vocabularies' or
 90+'schemas' that map concepts, object, and relationships to URIs. By
 91+popularizing such a mapping, we can all agree about what a particular
 92+URI "means".
 93+
 94+For example, the Dublin Core Metadata Initiative (DCMI)
 95+(http://www.dublincore.org/) has a schema for very simple metadata,
 96+such as you'd find on a library card. They've defined (among other
 97+things), that the idea of authoring or creating something is
 98+represented by the URL http://purl.org/dc/elements/1.1/creator. So
 99+you could say:
 100+
 101+ http://www.fsf.org http://purl.org/dc/elements/1.1/creator mailto:rms@gnu.org
 102+
 103+... means that the creator of the Free Software Foundation is Richard
 104+Stallman.
 105+
 106+There are a lot of RDF models out there; you can also create your own
 107+if you want.
 108+
 109+RDF statements can be encoded in a number of different ways. By far
 110+the most popular is as XML, sometimes called "RDF/XML". "Turtle" is
 111+another format, which uses plain text rather than XML; and "Ntriples"
 112+is still another.
 113+
 114+== Models ==
 115+
 116+For any given resource you can describe it from many different
 117+perspectives. For example, you can describe a man in terms of his
 118+academic career, his job experience, his family members, his body
 119+parts' size and weight, his location in space, his membership in
 120+organizations, his hobbies and interests, etc.
 121+
 122+In this extension, we use the term "model" to describe a perspective
 123+on a resource. For example, listing the links to and from a page is
 124+one model; its edit history is another model. You can choose which
 125+models you want to know about when querying the system for RDF
 126+statements about a subject, and only statements in that model are
 127+returned.
 128+
 129+This is mostly a concession to performance; it doesn't make sense to
 130+calculate information about the history of a page if calling program
 131+isn't going to use it.
 132+
 133+There are a number of models built into this extension; you can also
 134+add your own, if you know how to code PHP. The models have short
 135+little codenames for easy access, listed below.
 136+
 137+Models built in:
 138+
 139+ * dcmes: Dublin Core Metadata Element Set (DCMES) data. Mostly
 140+ information about who edited a page, when, and other simple stuff.
 141+ Titles, format, etc. This is a common vocabulary that's very
 142+ useful for general-purpose bots.
 143+ * cc: Creative Commons metadata. Gives license information; there
 144+ are a few tools and search engines that use this data.
 145+ * linksto, linksfrom, links: Internal wiki links to and from a page.
 146+ "links" is a shortcut for both.
 147+ * image: DCMES information about images in a page.
 148+ * history: version history of a page; who edited the page and when.
 149+ * interwiki: links to different language versions of a page.
 150+ * categories: which categories a page is in.
 151+ * inpage: a special model for blocks of RDF embedded into the source
 152+ code of MediaWiki pages; see "In-page RDF" below for info.
 153+
 154+== Special:RDF ==
 155+
 156+You can view RDF for a page using the [[Special:Rdf]] feature. It
 157+should be listed on the list of special pages as "Rdf". Enter the
 158+title of the page you want RDF for in the title box, and choose one or
 159+more of the RDF models from the multiselect box. You can also select
 160+which output format you want; XML is probably most useful and can be
 161+viewed in a browser.
 162+
 163+The Special:Rdf page can also be called directly, with the following
 164+parameters:
 165+
 166+ * target: title of the article to get RDF info about. If no target
 167+ URL is provided, the special page shows the input form.
 168+ * modelnames: comma-separated list of model names, like
 169+ "links,cc,history". Default is a list of standard models,
 170+ configurable per-site (see below).
 171+ * format: output format; one of 'xml', 'turtle' and 'ntriples'.
 172+ Default is XML.
 173+
 174+== In-page RDF ==
 175+
 176+Any user can make additional RDF statements about any resource by
 177+adding an in-page RDF block to the page. The RDF needs to be in Turtle
 178+format (http://www.dajobe.org/2004/01/turtle/), which is extremely
 179+simple. It's a subset of Notation3
 180+(http://www.w3.org/DesignIssues/Notation3.html), for which there is a
 181+good introduction. (http://www.w3.org/2000/10/swap/Primer.html)
 182+
 183+RDF blocks are delimited by the tag "<rdf>". They're invisible for
 184+normal output, but they can provide information for RDF-reading items.
 185+Here's an example:
 186+
 187+ Mathematics is ''very'' hard.
 188+
 189+ <rdf>
 190+ <> dc:subject "Mathematics"@en .
 191+ </rdf>
 192+
 193+Here, the rdf block says that the subject of the article is
 194+"Mathematics". Note that <> in Turtle means "this document". Another
 195+example:
 196+
 197+ Chilean wines are quite delicious.
 198+
 199+ <rdf>
 200+ <> dc:source <http://example.org/chileanwines.html> .
 201+ <http://example.org/chileanwines.html>
 202+ dc:creator "Bob Smith" .
 203+ </rdf>
 204+
 205+Here, we've said that the article's source is another Web page on
 206+another server; we can also say that that other Web page's author is
 207+Bob Smith.
 208+
 209+In-page RDF is displayed whenever the "inpage" model is requested for
 210+Special:RDF; it's one of the defaults. It's also useful for people
 211+making MediaWiki extensions; you can have users add information in
 212+in-page RDF, and then extract it and read it using the function
 213+MwRdfGetModel(). This lets users add data that isn't for presentation
 214+but perhaps for automated tools to use.
 215+
 216+Note also that MediaWiki templates are expanded when in-page RDF is
 217+queries. So if the syntax of Turtle is daunting, you can add templates
 218+that make it easier. For example, we could create a template
 219+Template:Source for showing source documents:
 220+
 221+ <rdf>
 222+ <> dc:source <{{{1}}}> .
 223+ <{{{1}}}> dc:creator "{{{2|anonymous}}}" .
 224+ </rdf>
 225+
 226+We could then make the same statement as above with a template
 227+transclusion:
 228+
 229+ {{source|http://example.org/chileanwines.html|Bob Smith}}
 230+
 231+Note that a number of namespaces are pre-defined for your RDF blocks.
 232+Some basic namespaces are provided by RAP; you can define custom
 233+namespaces with the global variable $wgRdfNamespaces . In addition,
 234+each of the article namespaces is mapped to a namespace prefix in
 235+Turtle, so you can say something like this:
 236+
 237+ <rdf>
 238+ Wikitravel_talk:Spelling dc:subject Wikitravel:Spelling .
 239+
 240+ :Montreal dc:spatial "Montreal" .
 241+ </rdf>
 242+
 243+Note that the default prefix (":") is the article namespace.
 244+
 245+== Customization ==
 246+
 247+There are a few customization variables available, mostly for
 248+programmers.
 249+
 250+$wgRdfDefaultModels -- an array of names of the default models to use
 251+ when no model name is specified.
 252+$wgRdfNamespaces -- You can add custom namespaces to this associative
 253+ array, of the form 'prefix' => 'uri' .
 254+$wgRdfModelFunctions -- an associative array mapping model names to
 255+ functions that generate the model. See below for
 256+ how to add a new model.
 257+$wgRdfOutputFunctions -- A map of output format to functions that
 258+ generate that output. You can add new output
 259+ formats by adding to this array.
 260+$wgRdfCacheExpiry -- time in seconds to expire cached items
 261+
 262+== Extending ==
 263+
 264+You can add new RDF models to the framework by creating a model
 265+function and adding it to the $wgRdfModelFunctions array. The function
 266+will get a single MediaWiki Article object as a parameter; it should
 267+return a single RAP Model object (a collection of statements) as a
 268+result. For example,
 269+
 270+ function CharacterCount($article) {
 271+ # create a new model
 272+ $model = ModelFactory::getDefaultModel();
 273+ # get the article source
 274+ $text = $article->getContent(true);
 275+ # ... and its size
 276+ $size = mb_strlen($text);
 277+ # Get the resource for this article
 278+ $ar = MwRdfArticleResource($article);
 279+ # Add a statement to the model
 280+ $model->add(new Statement($ar, new Resource("http://example.org/charcount"),
 281+ new Literal($size)));
 282+ # return the model
 283+ return $model;
 284+ }
 285+
 286+You can then give the model a name like so:
 287+
 288+$wgRdfModelFunctions['charcount'] = 'CharacterCount';
 289+
 290+You can add a message to the site describing your model like so:
 291+
 292+$wgMessageCache->addMessages(array('rdf-charcount' => 'Count of characters'));
 293+
 294+You can also create model-outputting functions if you so desire; they
 295+should accept a RAP model as input and make output as they would to
 296+the Web. This is probably only useful if you want a specific RDF
 297+encoding mechanism that's not RDF/XML, Turtle, or Ntriples; for
 298+example, TriG or TriX.
 299+
 300+== Future ==
 301+
 302+These are some future directions I'd like to see things go:
 303+
 304+* Store statements in DB: statements could be stored in the database
 305+ when the page is saved and retrieved when needed. This would make it
 306+ possible to do extended queries based on information about *all* pages.
 307+* Performance: there wasn't much performance tuning and there are
 308+ probably way too many DB hits and reads and such.
 309+* Semantic tuning: I'd like to make sure that the statements in the
 310+ standard models are accurate and useful.
 311+
 312+== Bugs ==
 313+
 314+Send bug reports, patches, and feature requests to Evan Prodromou
 315+<evan@wikitravel.org> .
Property changes on: trunk/extensions/Rdf/README.RDF.txt
___________________________________________________________________
Name: svn:keywords
1316 + Author Date Id Revision
Name: svn:eol-style
2317 + native
Index: trunk/extensions/Rdf/TODO
@@ -0,0 +1,3 @@
 2+* Store statements in database on save
 3+* Optimize
 4+
Property changes on: trunk/extensions/Rdf/TODO
___________________________________________________________________
Name: svn:keywords
15 + Author Date Id Revision
Name: svn:eol-style
26 + native
Index: trunk/extensions/Rdf/COPYING
@@ -0,0 +1,340 @@
 2+ GNU GENERAL PUBLIC LICENSE
 3+ Version 2, June 1991
 4+
 5+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 6+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 7+ Everyone is permitted to copy and distribute verbatim copies
 8+ of this license document, but changing it is not allowed.
 9+
 10+ Preamble
 11+
 12+ The licenses for most software are designed to take away your
 13+freedom to share and change it. By contrast, the GNU General Public
 14+License is intended to guarantee your freedom to share and change free
 15+software--to make sure the software is free for all its users. This
 16+General Public License applies to most of the Free Software
 17+Foundation's software and to any other program whose authors commit to
 18+using it. (Some other Free Software Foundation software is covered by
 19+the GNU Library General Public License instead.) You can apply it to
 20+your programs, too.
 21+
 22+ When we speak of free software, we are referring to freedom, not
 23+price. Our General Public Licenses are designed to make sure that you
 24+have the freedom to distribute copies of free software (and charge for
 25+this service if you wish), that you receive source code or can get it
 26+if you want it, that you can change the software or use pieces of it
 27+in new free programs; and that you know you can do these things.
 28+
 29+ To protect your rights, we need to make restrictions that forbid
 30+anyone to deny you these rights or to ask you to surrender the rights.
 31+These restrictions translate to certain responsibilities for you if you
 32+distribute copies of the software, or if you modify it.
 33+
 34+ For example, if you distribute copies of such a program, whether
 35+gratis or for a fee, you must give the recipients all the rights that
 36+you have. You must make sure that they, too, receive or can get the
 37+source code. And you must show them these terms so they know their
 38+rights.
 39+
 40+ We protect your rights with two steps: (1) copyright the software, and
 41+(2) offer you this license which gives you legal permission to copy,
 42+distribute and/or modify the software.
 43+
 44+ Also, for each author's protection and ours, we want to make certain
 45+that everyone understands that there is no warranty for this free
 46+software. If the software is modified by someone else and passed on, we
 47+want its recipients to know that what they have is not the original, so
 48+that any problems introduced by others will not reflect on the original
 49+authors' reputations.
 50+
 51+ Finally, any free program is threatened constantly by software
 52+patents. We wish to avoid the danger that redistributors of a free
 53+program will individually obtain patent licenses, in effect making the
 54+program proprietary. To prevent this, we have made it clear that any
 55+patent must be licensed for everyone's free use or not licensed at all.
 56+
 57+ The precise terms and conditions for copying, distribution and
 58+modification follow.
 59+
 60+ GNU GENERAL PUBLIC LICENSE
 61+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 62+
 63+ 0. This License applies to any program or other work which contains
 64+a notice placed by the copyright holder saying it may be distributed
 65+under the terms of this General Public License. The "Program", below,
 66+refers to any such program or work, and a "work based on the Program"
 67+means either the Program or any derivative work under copyright law:
 68+that is to say, a work containing the Program or a portion of it,
 69+either verbatim or with modifications and/or translated into another
 70+language. (Hereinafter, translation is included without limitation in
 71+the term "modification".) Each licensee is addressed as "you".
 72+
 73+Activities other than copying, distribution and modification are not
 74+covered by this License; they are outside its scope. The act of
 75+running the Program is not restricted, and the output from the Program
 76+is covered only if its contents constitute a work based on the
 77+Program (independent of having been made by running the Program).
 78+Whether that is true depends on what the Program does.
 79+
 80+ 1. You may copy and distribute verbatim copies of the Program's
 81+source code as you receive it, in any medium, provided that you
 82+conspicuously and appropriately publish on each copy an appropriate
 83+copyright notice and disclaimer of warranty; keep intact all the
 84+notices that refer to this License and to the absence of any warranty;
 85+and give any other recipients of the Program a copy of this License
 86+along with the Program.
 87+
 88+You may charge a fee for the physical act of transferring a copy, and
 89+you may at your option offer warranty protection in exchange for a fee.
 90+
 91+ 2. You may modify your copy or copies of the Program or any portion
 92+of it, thus forming a work based on the Program, and copy and
 93+distribute such modifications or work under the terms of Section 1
 94+above, provided that you also meet all of these conditions:
 95+
 96+ a) You must cause the modified files to carry prominent notices
 97+ stating that you changed the files and the date of any change.
 98+
 99+ b) You must cause any work that you distribute or publish, that in
 100+ whole or in part contains or is derived from the Program or any
 101+ part thereof, to be licensed as a whole at no charge to all third
 102+ parties under the terms of this License.
 103+
 104+ c) If the modified program normally reads commands interactively
 105+ when run, you must cause it, when started running for such
 106+ interactive use in the most ordinary way, to print or display an
 107+ announcement including an appropriate copyright notice and a
 108+ notice that there is no warranty (or else, saying that you provide
 109+ a warranty) and that users may redistribute the program under
 110+ these conditions, and telling the user how to view a copy of this
 111+ License. (Exception: if the Program itself is interactive but
 112+ does not normally print such an announcement, your work based on
 113+ the Program is not required to print an announcement.)
 114+
 115+These requirements apply to the modified work as a whole. If
 116+identifiable sections of that work are not derived from the Program,
 117+and can be reasonably considered independent and separate works in
 118+themselves, then this License, and its terms, do not apply to those
 119+sections when you distribute them as separate works. But when you
 120+distribute the same sections as part of a whole which is a work based
 121+on the Program, the distribution of the whole must be on the terms of
 122+this License, whose permissions for other licensees extend to the
 123+entire whole, and thus to each and every part regardless of who wrote it.
 124+
 125+Thus, it is not the intent of this section to claim rights or contest
 126+your rights to work written entirely by you; rather, the intent is to
 127+exercise the right to control the distribution of derivative or
 128+collective works based on the Program.
 129+
 130+In addition, mere aggregation of another work not based on the Program
 131+with the Program (or with a work based on the Program) on a volume of
 132+a storage or distribution medium does not bring the other work under
 133+the scope of this License.
 134+
 135+ 3. You may copy and distribute the Program (or a work based on it,
 136+under Section 2) in object code or executable form under the terms of
 137+Sections 1 and 2 above provided that you also do one of the following:
 138+
 139+ a) Accompany it with the complete corresponding machine-readable
 140+ source code, which must be distributed under the terms of Sections
 141+ 1 and 2 above on a medium customarily used for software interchange; or,
 142+
 143+ b) Accompany it with a written offer, valid for at least three
 144+ years, to give any third party, for a charge no more than your
 145+ cost of physically performing source distribution, a complete
 146+ machine-readable copy of the corresponding source code, to be
 147+ distributed under the terms of Sections 1 and 2 above on a medium
 148+ customarily used for software interchange; or,
 149+
 150+ c) Accompany it with the information you received as to the offer
 151+ to distribute corresponding source code. (This alternative is
 152+ allowed only for noncommercial distribution and only if you
 153+ received the program in object code or executable form with such
 154+ an offer, in accord with Subsection b above.)
 155+
 156+The source code for a work means the preferred form of the work for
 157+making modifications to it. For an executable work, complete source
 158+code means all the source code for all modules it contains, plus any
 159+associated interface definition files, plus the scripts used to
 160+control compilation and installation of the executable. However, as a
 161+special exception, the source code distributed need not include
 162+anything that is normally distributed (in either source or binary
 163+form) with the major components (compiler, kernel, and so on) of the
 164+operating system on which the executable runs, unless that component
 165+itself accompanies the executable.
 166+
 167+If distribution of executable or object code is made by offering
 168+access to copy from a designated place, then offering equivalent
 169+access to copy the source code from the same place counts as
 170+distribution of the source code, even though third parties are not
 171+compelled to copy the source along with the object code.
 172+
 173+ 4. You may not copy, modify, sublicense, or distribute the Program
 174+except as expressly provided under this License. Any attempt
 175+otherwise to copy, modify, sublicense or distribute the Program is
 176+void, and will automatically terminate your rights under this License.
 177+However, parties who have received copies, or rights, from you under
 178+this License will not have their licenses terminated so long as such
 179+parties remain in full compliance.
 180+
 181+ 5. You are not required to accept this License, since you have not
 182+signed it. However, nothing else grants you permission to modify or
 183+distribute the Program or its derivative works. These actions are
 184+prohibited by law if you do not accept this License. Therefore, by
 185+modifying or distributing the Program (or any work based on the
 186+Program), you indicate your acceptance of this License to do so, and
 187+all its terms and conditions for copying, distributing or modifying
 188+the Program or works based on it.
 189+
 190+ 6. Each time you redistribute the Program (or any work based on the
 191+Program), the recipient automatically receives a license from the
 192+original licensor to copy, distribute or modify the Program subject to
 193+these terms and conditions. You may not impose any further
 194+restrictions on the recipients' exercise of the rights granted herein.
 195+You are not responsible for enforcing compliance by third parties to
 196+this License.
 197+
 198+ 7. If, as a consequence of a court judgment or allegation of patent
 199+infringement or for any other reason (not limited to patent issues),
 200+conditions are imposed on you (whether by court order, agreement or
 201+otherwise) that contradict the conditions of this License, they do not
 202+excuse you from the conditions of this License. If you cannot
 203+distribute so as to satisfy simultaneously your obligations under this
 204+License and any other pertinent obligations, then as a consequence you
 205+may not distribute the Program at all. For example, if a patent
 206+license would not permit royalty-free redistribution of the Program by
 207+all those who receive copies directly or indirectly through you, then
 208+the only way you could satisfy both it and this License would be to
 209+refrain entirely from distribution of the Program.
 210+
 211+If any portion of this section is held invalid or unenforceable under
 212+any particular circumstance, the balance of the section is intended to
 213+apply and the section as a whole is intended to apply in other
 214+circumstances.
 215+
 216+It is not the purpose of this section to induce you to infringe any
 217+patents or other property right claims or to contest validity of any
 218+such claims; this section has the sole purpose of protecting the
 219+integrity of the free software distribution system, which is
 220+implemented by public license practices. Many people have made
 221+generous contributions to the wide range of software distributed
 222+through that system in reliance on consistent application of that
 223+system; it is up to the author/donor to decide if he or she is willing
 224+to distribute software through any other system and a licensee cannot
 225+impose that choice.
 226+
 227+This section is intended to make thoroughly clear what is believed to
 228+be a consequence of the rest of this License.
 229+
 230+ 8. If the distribution and/or use of the Program is restricted in
 231+certain countries either by patents or by copyrighted interfaces, the
 232+original copyright holder who places the Program under this License
 233+may add an explicit geographical distribution limitation excluding
 234+those countries, so that distribution is permitted only in or among
 235+countries not thus excluded. In such case, this License incorporates
 236+the limitation as if written in the body of this License.
 237+
 238+ 9. The Free Software Foundation may publish revised and/or new versions
 239+of the General Public License from time to time. Such new versions will
 240+be similar in spirit to the present version, but may differ in detail to
 241+address new problems or concerns.
 242+
 243+Each version is given a distinguishing version number. If the Program
 244+specifies a version number of this License which applies to it and "any
 245+later version", you have the option of following the terms and conditions
 246+either of that version or of any later version published by the Free
 247+Software Foundation. If the Program does not specify a version number of
 248+this License, you may choose any version ever published by the Free Software
 249+Foundation.
 250+
 251+ 10. If you wish to incorporate parts of the Program into other free
 252+programs whose distribution conditions are different, write to the author
 253+to ask for permission. For software which is copyrighted by the Free
 254+Software Foundation, write to the Free Software Foundation; we sometimes
 255+make exceptions for this. Our decision will be guided by the two goals
 256+of preserving the free status of all derivatives of our free software and
 257+of promoting the sharing and reuse of software generally.
 258+
 259+ NO WARRANTY
 260+
 261+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 262+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
 263+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 264+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 265+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 266+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
 267+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
 268+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 269+REPAIR OR CORRECTION.
 270+
 271+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 272+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 273+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 274+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 275+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 276+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 277+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 278+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 279+POSSIBILITY OF SUCH DAMAGES.
 280+
 281+ END OF TERMS AND CONDITIONS
 282+
 283+ How to Apply These Terms to Your New Programs
 284+
 285+ If you develop a new program, and you want it to be of the greatest
 286+possible use to the public, the best way to achieve this is to make it
 287+free software which everyone can redistribute and change under these terms.
 288+
 289+ To do so, attach the following notices to the program. It is safest
 290+to attach them to the start of each source file to most effectively
 291+convey the exclusion of warranty; and each file should have at least
 292+the "copyright" line and a pointer to where the full notice is found.
 293+
 294+ <one line to give the program's name and a brief idea of what it does.>
 295+ Copyright (C) <year> <name of author>
 296+
 297+ This program is free software; you can redistribute it and/or modify
 298+ it under the terms of the GNU General Public License as published by
 299+ the Free Software Foundation; either version 2 of the License, or
 300+ (at your option) any later version.
 301+
 302+ This program is distributed in the hope that it will be useful,
 303+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 304+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 305+ GNU General Public License for more details.
 306+
 307+ You should have received a copy of the GNU General Public License
 308+ along with this program; if not, write to the Free Software
 309+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 310+
 311+
 312+Also add information on how to contact you by electronic and paper mail.
 313+
 314+If the program is interactive, make it output a short notice like this
 315+when it starts in an interactive mode:
 316+
 317+ Gnomovision version 69, Copyright (C) year name of author
 318+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 319+ This is free software, and you are welcome to redistribute it
 320+ under certain conditions; type `show c' for details.
 321+
 322+The hypothetical commands `show w' and `show c' should show the appropriate
 323+parts of the General Public License. Of course, the commands you use may
 324+be called something other than `show w' and `show c'; they could even be
 325+mouse-clicks or menu items--whatever suits your program.
 326+
 327+You should also get your employer (if you work as a programmer) or your
 328+school, if any, to sign a "copyright disclaimer" for the program, if
 329+necessary. Here is a sample; alter the names:
 330+
 331+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 332+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
 333+
 334+ <signature of Ty Coon>, 1 April 1989
 335+ Ty Coon, President of Vice
 336+
 337+This General Public License does not permit incorporating your program into
 338+proprietary programs. If your program is a subroutine library, you may
 339+consider it more useful to permit linking proprietary applications with the
 340+library. If this is what you want to do, use the GNU Library General
 341+Public License instead of this License.
Property changes on: trunk/extensions/Rdf/COPYING
___________________________________________________________________
Name: svn:keywords
1342 + Author Date Id Revision
Name: svn:eol-style
2343 + native

Status & tagging log