Подтверждаю сказанное нескромным AnotherBoris-ом.
1) Нужно взять равы из мастерворка и адаптировать автоматическое из них выдирание нужных кусков так, чтобы минимально затронуть работу вики ванильной. Я слабое представление имею, как это делается :).
На данном этапе интересуют воркшопы. В перспективе - также существа и вещи. Хотя если ориентироваться на вики англоязычную, существ может оказаться сделать изрядно просто (если на задаваться целью впихнуть в каждую статью кастомный кусок).
2) Меня интересуют картинки воркшопов. Сильно заколебался их руками вставлять. Они в сумме на пару мегабайт может завесят.
Мало того, можно сделать шаблон специальной плашки с картинкой и надписью "Эта статья относится к моду Мастерворк", и в которую включить тег группы.Стоит уже нечто подобное.
Что ты имеешь в виду под "подсунуть равки - получить статьи?". В принципе это возможно, фактически тебе нужно всего лишь написать текстовый парсер, который из подсунутых равок сделает шаблон в формате медиавики. Если шаришь в любом языке программирования, открыть/закрыть/построчно прочитать/записать текстовый файл, регулярные выражения, словари для уже имеющихся статей, чтобы делать медиавики линки и вперед.Парсер уже есть, но как я понял, есть вероятность затереть оригинальные равки, если они имеют одинаковые названия с равками из Мастерворка.
<?php
/*
* DFRawFunctions extension by Quietust
* Dwarf Fortress Raw parser functions
*/
if (!defined('MEDIAWIKI'))
{
echo "This file is an extension of the MediaWiki software and cannot be used standalone\n";
die(1);
}
$wgExtensionCredits['parserhook'][] = array(
'path' => __FILE__,
'name' => 'DFRawFunctions',
'author' => 'Quietust',
'url' => 'http://df.magmawiki.com/index.php/User:Quietust',
'version' => '1.0',
'description' => 'Dwarf Fortress Raw parser functions',
);
$wgHooks['ParserFirstCallInit'][] = 'efDFRawFunctions_Setup';
$wgHooks['LanguageGetMagic'][] = 'efDFRawFunctions_Magic';
function efDFRawFunctions_Setup (&$parser)
{
$parser->setFunctionHook('df_raw', 'DFRawFunctions::raw');
$parser->setFunctionHook('df_tag', 'DFRawFunctions::tag');
$parser->setFunctionHook('df_tagentry', 'DFRawFunctions::tagentry');
$parser->setFunctionHook('df_tagvalue', 'DFRawFunctions::tagvalue');
$parser->setFunctionHook('df_foreachtag', 'DFRawFunctions::foreachtag');
$parser->setFunctionHook('df_foreachtoken', 'DFRawFunctions::foreachtoken');
$parser->setFunctionHook('df_makelist', 'DFRawFunctions::makelist');
$parser->setFunctionHook('df_statedesc', 'DFRawFunctions::statedesc');
$parser->setFunctionHook('mreplace', 'DFRawFunctions::mreplace');
$parser->setFunctionHook('delay', 'DFRawFunctions::delay');
$parser->setFunctionHook('eval', 'DFRawFunctions::evaluate');
return true;
}
function efDFRawFunctions_Magic (&$magicWords, $langCode)
{
$magicWords['df_raw'] = array(0, 'df_raw');
$magicWords['df_tag'] = array(0, 'df_tag');
$magicWords['df_tagentry'] = array(0, 'df_tagentry');
$magicWords['df_tagvalue'] = array(0, 'df_tagvalue');
$magicWords['df_foreachtag'] = array(0, 'df_foreachtag');
$magicWords['df_foreachtoken'] = array(0, 'df_foreachtoken');
$magicWords['df_makelist'] = array(0, 'df_makelist');
$magicWords['df_statedesc'] = array(0, 'df_statedesc');
$magicWords['mreplace'] = array(0, 'mreplace');
$magicWords['delay'] = array(0, 'delay');
$magicWords['eval'] = array(0, 'eval');
return true;
}
class DFRawFunctions
{
// Takes some raws and returns a 2-dimensional token array
// If 2nd parameter is specified, then only tags of the specified type will be returned
private static function getTags ($data, $type = '')
{
$raws = array();
$off = 0;
while (1)
{
$start = strpos($data, '[', $off);
if ($start === FALSE)
break;
$end = strpos($data, ']', $start);
if ($end === FALSE)
break;
$off = $end + 1;
$tag = explode(':', substr($data, $start + 1, $end - $start - 1));
if (($type == '') || ($tag[0] == $type))
$raws[] = $tag;
}
return $raws;
}
// Take an entire raw file and extract one entity
public static function raw (&$parser, $data = '', $object = '', $id = '', $notfound = '')
{
$start = strpos($data, '['. $object .':'. $id .']');
if ($start === FALSE)
return $notfound;
$end = strpos($data, '['. $object .':', $start + 1);
if ($end === FALSE)
return substr($data, $start);
return substr($data, $start, $end - $start);
}
// Checks if a tag is present, optionally with a particular token at a specific offset
public static function tag (&$parser, $data = '', $type = '', $offset = 0, $entry = '')
{
if ($entry == '')
$entry = $type;
$tags = self::getTags($data, $type);
foreach ($tags as $tag)
{
if ($offset >= count($tag))
continue;
if ($tag[$offset] == $entry)
return TRUE;
}
return FALSE;
}
// Locates a tag matching certain criteria and returns the tag at the specified offset
// Match condition parameters are formatted CHECKOFFSET:CHECKVALUE
// If offset is of format MIN:MAX, then all tokens within the range will be returned, colon-separated
public static function tagentry (&$parser, $data = '', $type = '', $offset = 0, $notfound = 'not found')
{
$numcaps = func_num_args() - 5;
$tags = self::getTags($data, $type);
foreach ($tags as $tag)
{
if ($offset >= count($tag))
continue;
$match = true;
for ($i = 0; $i < $numcaps; $i++)
{
$parm = func_get_arg($i + 5);
list($checkoffset, $checkval) = explode(':', $parm);
if (($checkoffset >= count($tag)) || ($tag[$checkoffset] != $checkval))
{
$match = false;
break;
}
}
if ($match)
{
$range = explode(':', $offset);
if (count($range) == 1)
return $tag[$offset];
else
{
$out = array();
for ($i = $range[0]; $i <= $range[1]; $i++)
$out[] = $tag[$i];
return implode(':', $out);
}
}
}
return $notfound;
}
// Locates a tag and returns all of its tokens as a colon-separated string
public static function tagvalue (&$parser, $data = '', $type = '', $notfound = 'not found')
{
$tags = self::getTags($data, $type);
if (count($tags) == 0)
return $notfound;
$tag = $tags[0];
array_shift($tag);
return implode(':', $tag);
}
// Iterates across all matching tags and produces the string for each one, substituting \1, \2, etc. for the tokens
// Probably won't work with more than 9 parameters
public static function foreachtag (&$parser, $data = '', $type = '', $string = '')
{
$tags = self::getTags($data, $type);
$out = '';
foreach ($tags as $tag)
{
$rep_in = array();
for ($i = 0; $i < count($tag); $i++)
$rep_in[$i] = '\\'. ($i + 1);
$out .= str_replace($rep_in, $tag, $string);
}
return $out;
}
// Iterates across all tokens within a specific tag in groups and produces the string for each group, substituting \1, \2, etc.
// Input data is expected to come from tagvalue()
public static function foreachtoken (&$parser, $data = '', $offset = 0, $group = 1, $string = '')
{
$tag = explode(':', $data);
$out = '';
$rep_in = array();
for ($i = 0; $i < $group; $i++)
$rep_in[] = '\\'. ($i + 1);
for ($i = $offset; $i < count($tag); $i += $group)
{
$rep_out = array();
for ($j = 0; $j < $group; $j++)
$rep_out[] = $tag[$i + $j];
$out .= str_replace($rep_in, $rep_out, $string);
}
return $out;
}
// Iterates across all objects in the specified raw file and extracts specific tokens
// Token extraction parameters are formatted TYPE:OFFSET:CHECKOFFSET:CHECKVALUE
// If CHECKOFFSET is -1, then CHECKVALUE is ignored
// If TYPE is "STATE" and OFFSET is "NAME" or "ADJ", then OFFSET and CHECKOFFSET will be fed into statedesc() to return the material's state descriptor
// Objects which fail to match *any* of the checks will be skipped
public static function makelist (&$parser, $data = '', $object = '', $string = '')
{
$numcaps = func_num_args() - 4;
$rep_in = array();
for ($i = 0; $i < $numcaps; $i++)
$rep_in[$i] = '\\'. ($i + 1);
$out = '';
$off = 0;
while (1)
{
$start = strpos($data, '['. $object .':', $off);
if ($start === FALSE)
break;
$end = strpos($data, '['. $object .':', $start + 1);
if ($end === FALSE)
$end = strlen($data);
$off = $end;
$tags = self::getTags(substr($data, $start, $end - $start));
$rep_out = array();
for ($i = 0; $i < $numcaps; $i++)
{
$parm = func_get_arg($i + 4);
list($gettype, $getoffset, $checkoffset, $checkval) = explode(':', $parm);
// permit fetching material state descriptors from here
if (($gettype == 'STATE') && (in_array($getoffset, array('NAME', 'ADJ'))))
{
$val = self::statedesc($parser, substr($data, $start, $end - $start), $getoffset, $checkoffset);
if (strlen($val))
$rep_out[$i] = $val;
continue;
}
foreach ($tags as $tag)
{
if (($tag[0] != $gettype) || ($getoffset >= count($tag)))
continue;
if (($checkoffset < 0) || (($checkoffset < count($tag)) && ($tag[$checkoffset] == $checkval)))
{
$rep_out[$i] = $tag[$getoffset];
break;
}
}
}
if (count($rep_in) == count($rep_out))
$out .= str_replace($rep_in, $rep_out, $string);
}
return $out;
}
// Determines a material's state descriptor by parsing its raws
public static function statedesc (&$parser, $data = '', $type = '', $state = '')
{
$tags = self::getTags($data);
$names = array('NAME' => array(), 'ADJ' => array());
foreach ($tags as $tag)
{
if (in_array($tag[0], array('STATE_NAME', 'STATE_NAME_ADJ')))
{
if (in_array($tag[1], array('SOLID', 'ALL_SOLID')))
$names['NAME']['SOLID'] = $tag[2];
if (in_array($tag[1], array('SOLID_POWDER', 'POWDER', 'ALL_SOLID')))
$names['NAME']['POWDER'] = $tag[2];
if (in_array($tag[1], array('SOLID_PASTE', 'PASTE', 'ALL_SOLID')))
$names['NAME']['PASTE'] = $tag[2];
if (in_array($tag[1], array('SOLID_PRESSED', 'PRESSED', 'ALL_SOLID')))
$names['NAME']['PRESSED'] = $tag[2];
if ($tag[1] == 'LIQUID')
$names['NAME']['LIQUID'] = $tag[2];
if ($tag[1] == 'GAS')
$names['NAME']['GAS'] = $tag[2];
}
if (in_array($tag[0], array('STATE_ADJ', 'STATE_NAME_ADJ')))
{
if (in_array($tag[1], array('SOLID', 'ALL_SOLID')))
$names['ADJ']['SOLID'] = $tag[2];
if (in_array($tag[1], array('SOLID_POWDER', 'POWDER', 'ALL_SOLID')))
$names['ADJ']['POWDER'] = $tag[2];
if (in_array($tag[1], array('SOLID_PASTE', 'PASTE', 'ALL_SOLID')))
$names['ADJ']['PASTE'] = $tag[2];
if (in_array($tag[1], array('SOLID_PRESSED', 'PRESSED', 'ALL_SOLID')))
$names['ADJ']['PRESSED'] = $tag[2];
if ($tag[1] == 'LIQUID')
$names['ADJ']['LIQUID'] = $tag[2];
if ($tag[1] == 'GAS')
$names['ADJ']['GAS'] = $tag[2];
}
}
if (!isset($names[$type]))
return '';
if (!isset($names[$type][$state]))
return '';
return $names[$type][$state];
}
// Performs multiple string replacements
public static function mreplace (&$parser, $data = '')
{
$numargs = func_num_args() - 2;
$rep_in = array();
$rep_out = array();
for ($i = 0; $i < $numargs; $i += 2)
{
$rep_in[] = func_get_arg($i + 2);
if ($i == $numargs + 2)
$rep_out[] = '';
else $rep_out[] = func_get_arg($i + 3);
}
return str_replace($rep_in, $rep_out, $data);
}
public static function delay (&$parser)
{
$args = func_get_args();
array_shift($args);
return '{{'. implode('|', $args) .'}}';
}
// Evaluates any templates within the specified data - best used with foreachtag
public static function evaluate (&$parser, $data = '')
{
return $parser->replaceVariables($data);
}
}
поколупать парсер в боевых условиях.
Вероятно, она куда-то кидается через FTР. В ней и равы мастерворка есть. Это даст мне возможность поколупать парсер в боевых условиях.Я знаю, куда она кидается, потому что ранняя версия этого парсера у нас уже стояла. Версию обновил, вроде всё работает как прежде, что радует.
Странное дело. Я не нашел на русской вики ни одного случая использования этого раводера - #df_raw.Может быть кто-то уже перелопатил наши шаблоны на другой лад, я этим не занимался.
Может быть кто-то уже перелопатил наши шаблоны на другой лад, я этим не занимался.Хочешь сказать, раньше было по-другому?
$wgDFRawEnableDisk = true;
Проверил на самопальной вики - чудо случилось.
if (!$wgCommandLineMode) {
require_once "$IP/extensions/DFRawFunctions-master/DFRawFunctions.php";
}
if (!$wgCommandLineMode) {
require_once "$IP/extensions/DFRawFunctions-master/DFRawFunctions.body.php";
}
$wgDFRawEnableDisk = true;
[[{{#df_tagentry:{{#df_raw:Masterwork:profession_dwarf.txt|PROFESSION|DWARF}}|
{{#df_tagentry:{{#df_raw:Masterwork:building_kobold.txt|BUILDING_WORKSHOP|{{uc:{{PAGENAME}}}}|Unknown!}}|BUILD_LABOR|0|1|Unknown!|}}|0|1|Unknown!|}}]]
public static function raw_asva (&$parser, $data = '', $object = '', $s_type = '', $s_param = '', $l_type = '',$number = '', $notfound = ''){
$data = self::loadFile($data); $tags = self::getTags($data);
if (!$object)
return $data;
$e=0; $i = 0; $obj_numb=0; $return_value = ''; $tmp=array();
while ($tags[$i][0]!=FALSE){
if ($tags[$i][0]==$object){ // Checks if left tag fits OBJECT.
$obj_num=$obj_num+1; $affirmed_type=FALSE; $i_object=$i;
}
if ($obj_num>0){ // Made in case something's wrong with quotes.
if ($tags[$i][0] == $s_type and $tags[$i][1] == $s_param and $affirmed_type == FALSE) // Checks if TYPE:PARAMETER is present in the OBJECT. Puts flag and leaps back if yes.
{$affirmed_type = TRUE; $i=$i_object;}
if ($l_type == $tags[$i][0] and $affirmed_type == TRUE){
$tmp[$e] = $e+1 .") ". $tags[$i][1]; $e++;}
}
$i++;
}
//Test (hidden)
if ($number == '')
return implode(", ",$tmp);
if ($number == -1)
return "Last reaction of the TYPE is: ". $e .") ". $tmp[$e-1] .'.';
return $tmp[$number];
}
== Тест скрипта выдиральщика реакций для строения ==
{{spoiler|df_raw тест|{{#df_raw:Masterwork:reaction_kobold_small_asva.txt|REACTION|KOBOLD_EXTRACT_BLOOD}}
}}
'''All reactions:''' {{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME||Not found.}}.
# {{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME|0|Not found.}}
# {{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME|1|Not found.}}
# {{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME|2|Not found.}}
# {{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME|3|Not found.}}
{{#df_raw_asva:Masterwork:reaction_kobold.txt|REACTION|BUILDING|KITCHEN|NAME|-1|Not found.}}
Кусок текста
{{spoiler| описание спойлера | сам скрываемый текст}}
На всю страницу:
{{majorspoiler| текст }}
У кого есть права на редактирование главной, замените, пожалуйста, Что нового в 0.43.xx (http://dfwk.ru/Release_information/0.43) на Что нового в 0.44.xx (http://dfwk.ru/Release_information/0.44).Для этого права не нужны, там вставлен шаблон: http://dfwk.ru/Шаблон:News (http://dfwk.ru/Шаблон:News)