Wikivoyage:AutoWikiBrowser

Da Wikivoyage.
Jump to navigation Jump to search

AutoWikiBrowser (spesso abbreviato AWB) è un editor MediaWiki semi-automatico per Windows XP e versioni successive, progettato per effettuare le operazioni ripetitive e noiose in modo più semplice e veloce. Per l'installazione su sistemi Linux vedi la guida in inglese su questa pagina Ogni modifica fatta con AWB deve essere riesaminata manualmente prima di essere salvata, e (se necessario) bisogna applicare manualmente le correzioni necessarie. Per una guida più estesa vedi la relativa pagina su Wikipedia

Uso[modifica]

Le seguenti operazioni consentono l'uso di AWB su una macchina Windows con impostazioni per Wikivoyage.

Installare AWB[modifica]

  1. scarica l'ultima versione da qui
  2. Estrai il contenuto
  3. Doppio click su AutoWikiBrowser.exe per avviare AWB

Configurare AWB[modifica]

Configurare di AWB richiede l'impostazione di alcuni parametri e il caricamento di un set di impostazioni standard di AWB che sono stati adattati per Wikivoyage. Per la documentazione tecnica dettagliata vedi questa pagina

  1. Configura AWB per Wikivoyage. Seleziona Options → Preferences → Site → Project → Wikivoyage. e poi scegli la lingua. Nel nostro caso 'it'
  2. Imposta il login: Seleziona File → Log in/Profiles → Add → Login. Scrivi il tuo username e password in modo che le modifiche di AWB appaiano fatte dal tuo account.
  3. Importa la configurazione specifica per Wikivoyage. Copia il testo XML qui sotto e salvalo in un file con estensione .xml. Poi da AWB seleziona File → Log in/Profiles → Add → Login e premi Edit sul login da te salvato. Metti la spunta a "Select default settings" e inserisci il percorso del file xml. Una volta fatto il login potrai iniziare ad usare AWB per Wikivoyage.


file di configurazione AWB per Wikivoyage italiano
<?xml version="1.0" encoding="utf-8"?>
<AutoWikiBrowserPreferences xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:space="preserve" Version="5.5.6.0">
  <Project>wikivoyage</Project>
  <LanguageCode>it</LanguageCode>
  <CustomProject />
  <Protocol>http://</Protocol>
  <LoginDomain />
  <List>
    <ListSource />
    <SelectedProvider>CategoryListProvider</SelectedProvider>
    <ArticleList />
  </List>
  <FindAndReplace>
    <Enabled>true</Enabled>
    <IgnoreSomeText>false</IgnoreSomeText>
    <IgnoreMoreText>false</IgnoreMoreText>
    <AppendSummary>true</AppendSummary>
    <Replacements>
      <Replacement>
        <Find>\|thumbnail\|</Find>
        <Replace>|thumb|</Replace>
        <Comment />
        <IsRegex>false</IsRegex>
        <Enabled>true</Enabled>
        <Minor>true</Minor>
        <BeforeOrAfter>false</BeforeOrAfter>
        <RegularExpressionOptions>IgnoreCase</RegularExpressionOptions>
      </Replacement>
    </Replacements>
    <AdvancedReps />
    <SubstTemplates />
    <IncludeComments>false</IncludeComments>
    <ExpandRecursively>true</ExpandRecursively>
    <IgnoreUnformatted>false</IgnoreUnformatted>
  </FindAndReplace>
  <Editprefs>
    <GeneralFixes>true</GeneralFixes>
    <Tagger>false</Tagger>
    <Unicodify>true</Unicodify>
    <Recategorisation>0</Recategorisation>
    <NewCategory />
    <NewCategory2 />
    <ReImage>0</ReImage>
    <ImageFind />
    <Replace />
    <SkipIfNoCatChange>false</SkipIfNoCatChange>
    <RemoveSortKey>false</RemoveSortKey>
    <SkipIfNoImgChange>false</SkipIfNoImgChange>
    <AppendText>false</AppendText>
    <AppendTextMetaDataSort>false</AppendTextMetaDataSort>
    <Append>true</Append>
    <Text />
    <Newlines>2</Newlines>
    <AutoDelay>10</AutoDelay>
    <BotMaxEdits>0</BotMaxEdits>
    <SupressTag>false</SupressTag>
    <RegexTypoFix>true</RegexTypoFix>
  </Editprefs>
  <General>
    <AutoSaveEdit>
      <Enabled>false</Enabled>
      <SavePeriod>30</SavePeriod>
      <SaveFile />
    </AutoSaveEdit>
    <SelectedSummary>correzioni</SelectedSummary>
    <Summaries>
      <string>correzioni</string>
      <string>typo</string>
      <string>fix vari</string>
      <string>sistemo</string>
    </Summaries>
    <PasteMore>
      <string />
      <string />
      <string />
      <string />
      <string />
      <string />
      <string />
      <string />
      <string />
      <string />
    </PasteMore>
    <FindText />
    <FindRegex>false</FindRegex>
    <FindCaseSensitive>false</FindCaseSensitive>
    <WordWrap>true</WordWrap>
    <ToolBarEnabled>true</ToolBarEnabled>
    <BypassRedirect>true</BypassRedirect>
    <AutoSaveSettings>true</AutoSaveSettings>
    <noSectionEditSummary>false</noSectionEditSummary>
    <restrictDefaultsortAddition>true</restrictDefaultsortAddition>
    <restrictOrphanTagging>true</restrictOrphanTagging>
    <noMOSComplianceFixes>true</noMOSComplianceFixes>
    <syntaxHighlightEditBox>false</syntaxHighlightEditBox>
    <highlightAllFind>false</highlightAllFind>
    <PreParseMode>false</PreParseMode>
    <NoAutoChanges>false</NoAutoChanges>
    <OnLoadAction>0</OnLoadAction>
    <DiffInBotMode>false</DiffInBotMode>
    <Minor>true</Minor>
    <AddToWatchlist>2</AddToWatchlist>
    <TimerEnabled>false</TimerEnabled>
    <SortListAlphabetically>true</SortListAlphabetically>
    <AddIgnoredToLog>false</AddIgnoredToLog>
    <EditToolbarEnabled>true</EditToolbarEnabled>
    <filterNonMainSpace>false</filterNonMainSpace>
    <AutoFilterDuplicates>true</AutoFilterDuplicates>
    <FocusAtEndOfEditBox>false</FocusAtEndOfEditBox>
    <scrollToUnbalancedBrackets>false</scrollToUnbalancedBrackets>
    <TextBoxSize>9</TextBoxSize>
    <TextBoxFont>Courier New</TextBoxFont>
    <LowThreadPriority>false</LowThreadPriority>
    <Beep>false</Beep>
    <Flash>false</Flash>
    <Minimize>false</Minimize>
    <LockSummary>false</LockSummary>
    <SaveArticleList>true</SaveArticleList>
    <SuppressUsingAWB>false</SuppressUsingAWB>
    <AddUsingAWBToActionSummaries>false</AddUsingAWBToActionSummaries>
    <IgnoreNoBots>false</IgnoreNoBots>
    <ClearPageListOnProjectChange>false</ClearPageListOnProjectChange>
    <SortInterWikiOrder>true</SortInterWikiOrder>
    <ReplaceReferenceTags>true</ReplaceReferenceTags>
    <LoggingEnabled>true</LoggingEnabled>
    <AlertPreferences>
      <int>1</int>
      <int>2</int>
      <int>3</int>
      <int>4</int>
      <int>5</int>
      <int>6</int>
      <int>7</int>
      <int>8</int>
      <int>9</int>
      <int>10</int>
      <int>11</int>
      <int>12</int>
      <int>13</int>
      <int>14</int>
      <int>15</int>
      <int>16</int>
      <int>17</int>
      <int>18</int>
      <int>19</int>
      <int>20</int>
      <int>21</int>
    </AlertPreferences>
  </General>
  <SkipOptions>
    <SkipNonexistent>true</SkipNonexistent>
    <Skipexistent>false</Skipexistent>
    <SkipWhenNoChanges>true</SkipWhenNoChanges>
    <SkipSpamFilterBlocked>false</SkipSpamFilterBlocked>
    <SkipInuse>false</SkipInuse>
    <SkipWhenOnlyWhitespaceChanged>true</SkipWhenOnlyWhitespaceChanged>
    <SkipOnlyGeneralFixChanges>true</SkipOnlyGeneralFixChanges>
    <SkipOnlyMinorGeneralFixChanges>false</SkipOnlyMinorGeneralFixChanges>
    <SkipOnlyCosmetic>false</SkipOnlyCosmetic>
    <SkipOnlyCasingChanged>false</SkipOnlyCasingChanged>
    <SkipIfRedirect>false</SkipIfRedirect>
    <SkipIfNoAlerts>false</SkipIfNoAlerts>
    <SkipDoes>false</SkipDoes>
    <SkipDoesNot>false</SkipDoesNot>
    <SkipDoesText />
    <SkipDoesNotText />
    <Regex>false</Regex>
    <CaseSensitive>false</CaseSensitive>
    <AfterProcessing>false</AfterProcessing>
    <SkipNoFindAndReplace>false</SkipNoFindAndReplace>
    <SkipMinorFindAndReplace>false</SkipMinorFindAndReplace>
    <SkipNoRegexTypoFix>false</SkipNoRegexTypoFix>
    <SkipNoDisambiguation>false</SkipNoDisambiguation>
    <SkipNoLinksOnPage>false</SkipNoLinksOnPage>
    <GeneralSkipList />
  </SkipOptions>
  <Module>
    <Enabled>true</Enabled>
    <Language>C# 3.5</Language>
    <Code>// implementing the "aggressive" rules is more likely to produce false positives
private static readonly bool AGGRESSIVE = true;
private static readonly Regex ListingTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("listing,see,do,buy,eat,drink,sleep".Split(',')));
private static readonly string[] ListingTemplateParamNames = {"type","nome","alt","sito","email","indirizzo","lat","long","indicazioni","tel","numero verde","fax","orari","checkin","checkout","prezzo","descrizione"};
private static readonly string[] ListingPhoneParamNames = {"tel","fax","numero verde"};
private static readonly Regex PhoneNumberRegex = new Regex(@"'*[\d\+\(][\s\d\(\)\-\.'\+]+[\d\)]'*");
private static readonly Regex MailtoRegex = new Regex(@"mailto:[/]*", RegexOptions.IgnoreCase);
private static readonly Regex ExcessWhitespaceRegex = new Regex(@"\s\s+", RegexOptions.Singleline);
// "http://www.example.com"
private static readonly string ValidUrlPattern = @"((http(s)?:)//)?(([a-z]+\.)+)([a-z]+)";
private static readonly Regex ValidUrlRegex = new Regex(ValidUrlPattern, RegexOptions.Singleline | RegexOptions.IgnoreCase);
// "[http://www.example.com]"
private static readonly Regex FootnoteUrlRegex = new Regex(@"\[(" + ValidUrlPattern + @"([^\]\s]+))\]", RegexOptions.Singleline);
// "Foo (disambiguation)"
private static readonly Regex CityNameWithDisambiguationRegex = new Regex(@"([^\(]+) \([^\)]+\)", RegexOptions.Singleline);
// "blah, CA 99999", "blah CA", etc
private static readonly Regex AddressWithStateOrZipRegex = new Regex(@"(.+)[\.,\-]+\s*(AL|alabama|AK|alaska|AZ|arizona|AR|arkansas|CA|california|CO|colorado|CT|connecticut|DC|DE|delaware|FL|florida|GA|georgia|HI|hawaii|ID|idaho|IL|illinois|IN|indiana|IA|iowa|KS|kansas|KY|kentucky|LA|louisiana|ME|maine|MD|maryland|MA|massachusetts|MI|michigan|MN|minnesota|MS|mississippi|MO|missouri|MT|montana|NE|nebraska|NV|nevada|NH|new hampshire|NJ|new jersey|NM|new mexico|NY|new york|NC|north carolina|ND|north dakota|OH|ohio|OK|oklahoma|OR|oregon|PA|pennsylvania|RI|rhode island|SC|south carolina|SD|south dakota|TN|tennessee|TX|texas|UT|utah|VT|vermont|VA|virginia|WA|washington|WV|west virginia|WI|wisconsin|WY|wyoming)([\s,\-]*[0-9]{5})?$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
// "* ", "** ", etc
private static readonly Regex EmptyListItemRegex = new Regex(@"^\*+\s*\n", RegexOptions.Multiline);
private static readonly Regex FootnoteToFrontLinkRegex = new Regex(@"('*)((?!The )\p{Lu}[\w\-'/]*[\w]( (e|del|di|da|&amp;|il|lo|la|le|per|\p{Lu}[\w\-'/]*[\w]))*)('*)[, ]*\[(http[^ ]+)( )*\]");
private static readonly Regex TimeValuesShouldUseColonAsSeperator = new Regex(@"\b([1-9]|10|11|12)\.([0-5][0-9])([ ]*)((a|p)\.?\s*m\.|(a|p)\.?\s*m\b)", RegexOptions.IgnoreCase);
private static readonly Regex TimeValuesSuffixAM = new Regex(@"\b([1-9]|10|11|12)(:[0-5][0-9])*[ ]*(a\.\s*m\.|a\s*m\b)", RegexOptions.IgnoreCase);
private static readonly Regex TimeValuesSuffixPM = new Regex(@"\b([1-9]|10|11|12)(:[0-5][0-9])*[ ]*(p\.\s*m\.|p\s*m\b)", RegexOptions.IgnoreCase);
private static readonly Regex ExternalToInternalLinkWikipedia = new Regex(@"\[http[s]?://it.wikipedia.org/wiki/([^\] ]+)[ ]+([^\]]+)]", RegexOptions.IgnoreCase);
private static readonly Regex ExternalToInternalLinkWikipediaNoText = new Regex(@"\[http[s]?://it.wikipedia.org/wiki/([^\] ]+)[ ]*]", RegexOptions.IgnoreCase);
private static readonly Regex ExternalToInternalLinkWikivoyage = new Regex(@"\[http[s]?://it.wikivoyage.org/wiki/([^\] ]+)[ ]+([^\]]+)]", RegexOptions.IgnoreCase);
private static readonly Regex ExternalToInternalLinkWikivoyageNoText = new Regex(@"\[http[s]?://it.wikivoyage.org/wiki/([^\] ]+)[ ]*]", RegexOptions.IgnoreCase);
// "* blah blah blah", "** blah blah blah", etc
private static readonly Regex CandidateListingItemRegex = new Regex(@"^\*+\s*([^\{]{2}.+)$", RegexOptions.Multiline);
private static readonly Regex ListingNameRegex = new Regex(@"(il\s+)*'''(.{3,}?)'''", RegexOptions.IgnoreCase);
// "[http://www.example.com/ Example Text]"
private static readonly Regex ExternalLinkWithTextRegex = new Regex(@"\[(http[^\]\s]+)\s+([^\]]+)\]", RegexOptions.IgnoreCase);
// "123-456-7890"
private static readonly string ListingPhoneNumber = @"((''|\+|\()*\d+(''|\)*)[\s\-]+)+(''|\+|\()*\d+(''|\)*)( ext\.? \d+)?";
private static readonly Regex ListingPhoneNumberRegex = new Regex(ListingPhoneNumber, RegexOptions.IgnoreCase);
// "fax: 123-456-7890"
private static readonly string ListingFaxNumber = @"(\(''|''\(|\()?fax(:)?(\s)*(" + ListingPhoneNumber + @")(''\)|\)''|\))?";
private static readonly Regex ListingFaxNumberRegex = new Regex(ListingFaxNumber, RegexOptions.IgnoreCase);
// "tele: 123-456-7890" and similar
private static readonly string ListingPhoneNumberWithLabel = @"(\(''|''\(|\()?(\u260e|chiama|call:telefono:|telephone|tel:|tel\.:|tel\.|tel|tel:|tel|ph:|ph\.:|ph\.|ph|\u260E)(\s)*(" + ListingPhoneNumber + @")(''\)|\)''|\))?";
private static readonly Regex ListingPhoneNumberWithLabelRegex = new Regex(ListingPhoneNumberWithLabel, RegexOptions.IgnoreCase);
// "toll-free: 123-456-7890" and similar
private static readonly string ListingTollfreeNumber = @"(\(''|''\(|\()?(toll[ \-]?free)(:)?(\s)*(" + ListingPhoneNumber + @")(''\)|\)''|\))?";
private static readonly Regex ListingTollfreeNumberRegex = new Regex(ListingTollfreeNumber, RegexOptions.IgnoreCase);
private static readonly string InvalidLeadingOrTrailingPunctuation = @",|\-|\*|\:|\–";
private static readonly string InvalidLeadingPunctuation = @"\.|!|\?|\)|\]|\}|&amp;mdash;";
private static readonly string InvalidTrailingPunctuation = @"\(|\[|\{";
private static readonly string InvalidDuplicatePunctuation = @"\.|!|\?|" + InvalidLeadingOrTrailingPunctuation;
private static readonly Regex InvalidLeadingPunctuationRegex = new Regex(@"^(\s|" + InvalidLeadingPunctuation + "|" + InvalidLeadingOrTrailingPunctuation + @")+", RegexOptions.Multiline);
private static readonly Regex InvalidTrailingPunctuationRegex = new Regex(@"(\s|" + InvalidTrailingPunctuation + "|" + InvalidLeadingOrTrailingPunctuation + @")+$", RegexOptions.Multiline);
private static readonly Regex InvalidDuplicatePunctuationRegex = new Regex(@"(" + InvalidDuplicatePunctuation + @"|\s)+(" + InvalidDuplicatePunctuation + @")");
// "email: foo@bar.com" OR "mailto:foo@bar.com" OR "foo@bar.com"
private static readonly string ListingEmail = @"(mailto:|e-mail:)?\s*(\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b)";
private static readonly Regex ListingEmailRegex = new Regex(ListingEmail, RegexOptions.IgnoreCase);
// "1234 First St"
private static readonly string ListingAddress = @"([\d]+([/\-][\d]+)? ([nesw]\.? )?([\p{L}\d]+[ \.\-]*){1,3} (avenue|ave|av|boulevard|blvd|court|ct|drive|dr|expressway|expwy|freeway|fwy|highway( \d{1,3})?|hwy( \d{1,3})?|lane|ln|loop|parkway|pkwy|place|pl|road|rd|row|street|st|way|via|viale|piazza|gåta|väg|Straße|Strasse|parcheggio|statale|ulica|ulitsa|uliza|vicolo)\b(\.? (#(\s)*[\d]+|nord|nordest|Nord|Est|NO|N|Est|E|Sud|SE|SO|S|Ovest|O)\b)?)[\. , ]*";
private static readonly Regex ListingAddressRegex = new Regex(ListingAddress, RegexOptions.IgnoreCase);
// the above pattern will match things like "25 km by road", so add a pattern to catch those
private static readonly string ListingAddressFalsePositives = @"\b(km|kilometer|kilometers|mi|mile|miles)\b";
private static readonly Regex ListingAddressFalsePositivesRegex = new Regex(ListingAddressFalsePositives, RegexOptions.IgnoreCase);
// "Calle Ricardo Montalban, 452"
private static readonly string ListingAddressInternational = @"(avenida|ave|av|calle|estrada|est|rua)(\.)? ([\p{L}\d]+[ \.\-]*){1,3}, [\d]+([/\-][\d]+)?";
private static readonly Regex ListingAddressInternationalRegex = new Regex(ListingAddressInternational, RegexOptions.IgnoreCase);
private static readonly Regex ListingAddressIsDirectionsRegex = new Regex(@"^(between|corner|end|next|on|)\s", RegexOptions.Multiline);
//private static readonly Regex CityStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinecity,usablecity,guidecity,starcity".Split(',')));
//private static readonly Regex CountryStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinecountry,usablecountry,guidecountry,starcountry".Split(',')));
//private static readonly Regex DiveguideStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinediveguide,usablediveguide,guidediveguide,stardiveguide".Split(',')));
//private static readonly Regex DistrictStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;/("outlinedistrict,usabledistrict,guidedistrict,stardistrict".Split(',')));
//private static readonly Regex ItineraryStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlineitinerary,usableitinerary,guideitinerary,staritinerary".Split(',')));
//private static readonly Regex ParkStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinepark,usablepark,guidepark,starpark".Split(',')));
//private static readonly Regex PhrasebookStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinephrasebook,usablephrasebook,guidephrasebook,starphrasebook".Split(',')));
//private static readonly Regex RegionStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlineregion,usableregion,guideregion,starregion".Split(',')));
//private static readonly Regex TopicStatusTemplateNamesRegex = Tools.NestedTemplateRegex(new List&lt;string&gt;("outlinetopic,usabletopic,guidetopic,startopic".Split(',')));
//private static readonly Regex ListingAltParamRegex = new Regex(@"\|\s*alt\s*=", RegexOptions.Singleline);
// "()", "[]", "{}"
private static readonly Regex EmptyPunctuationRegex = new Regex(@"(\(\s*\)|\[\s*\]|\{\s*\})");
private static readonly Regex OnlyPunctuationRegex = new Regex(@"^['\-\(\)\[\]\{\}\*\.\?!\s]+$", RegexOptions.Singleline);
// match a single digit
private static readonly Regex DigitRegex = new Regex(@"\d");
private static readonly Regex DoubleSpaceRegex = new Regex(@"\s{2,}");
private static readonly Regex InvalidGetInHeadingRegex = new Regex(@"^(get in|Arrivare|come arrivare|getting in|getting there)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidGetAroundHeadingRegex = new Regex(@"^(get around|getting around)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidSeeHeadingRegex = new Regex(@"^(Monumenti|monumenti|Vedere|Attrazioni|attrazioni)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidDoHeadingRegex = new Regex(@"^(Attività|Tempo libero)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidBuyHeadingRegex = new Regex(@"^(shopping|negozi)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidEatHeadingRegex = new Regex(@"^(ristoranti|a pranzo|Mangiare)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidDrinkHeadingRegex = new Regex(@"^(bars|nightlife)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidSleepHeadingRegex = new Regex(@"^(accommodation|hotels)", RegexOptions.IgnoreCase);
private static readonly Regex InvalidGoNextHeadingRegex = new Regex(@"^(nei dintorni|Uscire)", RegexOptions.IgnoreCase);
private static readonly Regex MidrangeHeadingRegex = new Regex(@"^prezzi[ \-]*modici", RegexOptions.IgnoreCase);
private static readonly Regex ByOnHeadingRegex = new Regex(@"^(presso|su) (.+)", RegexOptions.IgnoreCase);
public string ProcessArticle(string articleText, string articleTitle, int wikiNamespace, out string summary, out bool skip) {
	string originalText = articleText;
	summary = "";
	skip = false;
	articleText = UpdateHeadings(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	articleText = ExternalToInternalLink(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	articleText = FootnoteToFrontlink(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	articleText = FormatTimeValues(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	if (AGGRESSIVE) {
		articleText = ConvertTextToListings(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	}
	articleText = FormatListings(articleText, articleTitle, wikiNamespace, ref summary, ref skip);
	if (articleText.Equals(originalText)) {
		skip = true;
	}
	return articleText;
}
// ensure that headings match the article templates
public string UpdateHeadings(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) { 
	foreach(Match m in WikiRegexes.Headings.Matches(articleText)) {
		string originalHeading = m.Value;
		string originalTitle = m.Groups[1].Value;
		string newTitle = originalTitle;
		string lowerTitle = originalTitle.ToLower().Trim();
		int headingLevel = 1;
		while (originalHeading[headingLevel] == '=') {
			headingLevel++;
		}
		Match match = null;
		if (headingLevel == 2) {
			if (MatchText(lowerTitle, InvalidGetInHeadingRegex, ref match)) {
				newTitle = "Come arrivare";
			} else if (MatchText(lowerTitle, InvalidGetAroundHeadingRegex, ref match)) {
				newTitle = "Come spostarsi";
			} else if (MatchText(lowerTitle, InvalidSeeHeadingRegex, ref match)) {
				newTitle = "Cosa vedere";
			} else if (MatchText(lowerTitle, InvalidDoHeadingRegex, ref match)) {
				newTitle = "Cosa fare";
			} else if (MatchText(lowerTitle, InvalidBuyHeadingRegex, ref match)) {
				newTitle = "Acquisti";
			} else if (MatchText(lowerTitle, InvalidEatHeadingRegex, ref match)) {
				newTitle = "Dove mangiare";
			} else if (MatchText(lowerTitle, InvalidDrinkHeadingRegex, ref match)) {
				newTitle = "Come divertirsi";
			} else if (MatchText(lowerTitle, InvalidSleepHeadingRegex, ref match)) {
				newTitle = "Dove alloggiare";
			} else if (MatchText(lowerTitle, InvalidGoNextHeadingRegex, ref match)) {
				newTitle = "Nei dintorni";
			}
		} else {
			if (MatchText(lowerTitle, MidrangeHeadingRegex, ref match)) {
				newTitle = "Prezzi modici";
			} else if (MatchText(lowerTitle, ByOnHeadingRegex, ref match)) {
				newTitle = Capitalize(match.Groups[1].Value) + " " + match.Groups[2].Value.ToLower();
			}
		}
		if (!newTitle.Equals(originalTitle)) {
			string headingBars = originalHeading.Substring(0, headingLevel);
			articleText = articleText.Replace(originalHeading, headingBars + newTitle + headingBars);
			summary = UpdateEditSummary(summary, "sistemo sezioni");
		}
	}
	return articleText;
}

// convert footnote links to frontlinks
public string FootnoteToFrontlink(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) {
	string originalText = articleText;
	articleText = FootnoteToFrontLinkRegex.Replace(articleText, "$1[$6 $2]$5");
	if (!articleText.Equals(originalText)) {
		summary = UpdateEditSummary(summary, "sistemo note");
	}
	return articleText;
}
// convert external links to interwiki/internal links
public string ExternalToInternalLink(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) {
	string originalText = articleText;
	articleText = ExternalToInternalLinkWikipedia.Replace(articleText, "[[w:$1|$2]]");
	articleText = ExternalToInternalLinkWikipediaNoText.Replace(articleText, "[[w:$1]]");
	articleText = ExternalToInternalLinkWikivoyage.Replace(articleText, "[[$1|$2]]");
	articleText = ExternalToInternalLinkWikivoyageNoText.Replace(articleText, "[[$1]]");
	if (!articleText.Equals(originalText)) {
		summary = UpdateEditSummary(summary, "fix link");
	}
	return articleText;
}
public string FormatTimeValues(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) {
	string originalText = articleText;
	articleText = TimeValuesShouldUseColonAsSeperator.Replace(articleText, "$1:$2$3$4");
	articleText = TimeValuesSuffixAM.Replace(articleText, "$1$2AM");
	articleText = TimeValuesSuffixPM.Replace(articleText, "$1$2PM");
	if (!articleText.Equals(originalText)) {
		summary = UpdateEditSummary(summary, "sistemo date");
	}
	return articleText;
}
public string ConvertTextToListings(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) {
	//if (!IsCityArticle(articleText) &amp;&amp; !IsDistrictArticle(articleText) &amp;&amp; !IsParkArticle(articleText)) {
		// do not try to convert text to listings for non-city or park articles
		//return articleText;
	//}
	string originalText = articleText;
	// loop through all sections
	foreach(KeyValuePair&lt;string, string&gt; sectionData in SplitToSecondLevelSections(articleText)) {
		string sectionName = sectionData.Key;
		if (!sectionName.ToLower().Equals("see") &amp;&amp; !sectionName.ToLower().Equals("do") &amp;&amp; !sectionName.ToLower().Equals("buy") &amp;&amp; !sectionName.ToLower().Equals("eat") &amp;&amp; !sectionName.ToLower().Equals("drink") &amp;&amp; !sectionName.ToLower().Equals("sleep")) {
			// only convert text that's in a section that supports non-generic listings
			continue;
		}
		string listingType = GetValidListingTypeForSection(sectionName);
		string sectionText = sectionData.Value;
		// get all list items within the section

		foreach(Match m in CandidateListingItemRegex.Matches(sectionText)) {
			string listItemText = m.Groups[1].Value;
			string templateCall = ConvertListingItemtoTemplatedListing(listItemText, listingType, ref summary);
			if (templateCall != "") {
				articleText = articleText.Replace(listItemText, templateCall);
				summary = UpdateEditSummary(summary, "converto in listing");
			}
		}
	}
	return articleText;
}
public string ConvertListingItemtoTemplatedListing(string listItemText, string listingType, ref string summary) {
	string templateCall = "{{" + listingType + "}}";
	if (!ProcessListingNameInListItem(ref listItemText, ref templateCall)) {
		// if we don't have a listing name don't bother trying to convert anything else
		return "";
	}
	ProcessListingPhoneInListItem(ref listItemText, ref templateCall);
	ProcessListingEmailInListItem(ref listItemText, ref templateCall);
	ProcessListingUrlInListItem(ref listItemText, ref templateCall);
	ProcessListingAddressInListItem(ref listItemText, ref templateCall);
	ProcessListingContentInListItem(ref listItemText, ref templateCall);
	return templateCall;
}
private bool ProcessListingNameInListItem(ref string listItemText, ref string templateCall) {
	Match m = ListingNameRegex.Match(listItemText);
	if (!m.Success || m.Index != 0) {
		// if there isn't a name at the beginning of the listing, don't convert
		return false;
	}
	string nome = m.Groups[2].Value;
	templateCall = Tools.SetTemplateParameterValue(templateCall, "nome", nome);
	// see if the nome is front-linked
	Match sitoMatch = ExternalLinkWithTextRegex.Match(nome);
	if (sitoMatch.Success &amp;&amp; sitoMatch.Index == 0) {
		// split the nome &amp; sito fields
		string sito = sitoMatch.Groups[1].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "sito", sito);
		nome = sitoMatch.Groups[2].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "nome", nome);
	}
	// remove nome from list item text
	listItemText = RemoveValueFromListItemText(listItemText, m.Value);
	return true;
}
private void ProcessListingPhoneInListItem(ref string listItemText, ref string templateCall) {
	Match telMatch = ListingPhoneNumberWithLabelRegex.Match(listItemText);
	if (telMatch.Success) {
		string tel = telMatch.Groups[4].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "tel", tel);
		listItemText = RemoveValueFromListItemText(listItemText, telMatch.Value);
	}
	Match faxMatch = ListingFaxNumberRegex.Match(listItemText);
	if (faxMatch.Success) {
		string fax = faxMatch.Groups[4].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "fax", fax);
		listItemText = RemoveValueFromListItemText(listItemText, faxMatch.Value);
	}
	Match tollfreeMatch = ListingTollfreeNumberRegex.Match(listItemText);
	if (tollfreeMatch.Success) {
		string tollfree = tollfreeMatch.Groups[5].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "tollfree", "numero verde");
		listItemText = RemoveValueFromListItemText(listItemText, tollfreeMatch.Value);
	}
	if (!telMatch.Success) {
		// try to find a tel number without a label
		telMatch = ListingPhoneNumberRegex.Match(listItemText);
		if (telMatch.Success) {
			string tel = telMatch.Value;
			if (DigitRegex.Matches(tel).Count &gt; 6) {
				// only consider a tel number valid if it contains more than six digits
				templateCall = Tools.SetTemplateParameterValue(templateCall, "tel", tel);
				listItemText = RemoveValueFromListItemText(listItemText, telMatch.Value);
			}
		}
	}
}
private void ProcessListingEmailInListItem(ref string listItemText, ref string templateCall) {
	Match emailMatch = ListingEmailRegex.Match(listItemText);
	if (emailMatch.Success) {
		string email = emailMatch.Groups[2].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "email", email);
		listItemText = RemoveValueFromListItemText(listItemText, emailMatch.Value);
	}
}
private void ProcessListingUrlInListItem(ref string listItemText, ref string templateCall) {
	if (Tools.GetTemplateParameterValue(templateCall, "sito") != "") {
		// sito was already set when processing listing nome
		return;
	}
	Match sitoMatch = FootnoteUrlRegex.Match(listItemText);
	if (sitoMatch.Success) {
		string sito = sitoMatch.Groups[1].Value;
		templateCall = Tools.SetTemplateParameterValue(templateCall, "sito", sito);
		listItemText = RemoveValueFromListItemText(listItemText, sitoMatch.Value);
	}
}
private void ProcessListingAddressInListItem(ref string listItemText, ref string templateCall) {
	Match indirizzoMatch = ListingAddressRegex.Match(listItemText);
	if (indirizzoMatch.Success) {
		string indirizzo = indirizzoMatch.Groups[1].Value;
		Match falsePositiveMatch = ListingAddressFalsePositivesRegex.Match(indirizzo);
		if (!falsePositiveMatch.Success) {
			templateCall = Tools.SetTemplateParameterValue(templateCall, "indirizzo", indirizzo);
			listItemText = RemoveValueFromListItemText(listItemText, indirizzoMatch.Value);
		}
	} else {
		indirizzoMatch = ListingAddressInternationalRegex.Match(listItemText);
		if (indirizzoMatch.Success) {
			string indirizzo = indirizzoMatch.Groups[1].Value;
			templateCall = Tools.SetTemplateParameterValue(templateCall, "indirizzo", indirizzo);
			listItemText = RemoveValueFromListItemText(listItemText, indirizzoMatch.Value);
		}
	}
}
private void ProcessListingContentInListItem(ref string listItemText, ref string templateCall) {
	if (String.IsNullOrEmpty(listItemText)) {
		return;
	}
	// strip empty punctuation
	listItemText = EmptyPunctuationRegex.Replace(listItemText, "");
	// strip sentence fragments left over from removing the listing nome
	if (listItemText.ToLower().StartsWith("is ")) {
		listItemText = listItemText.Substring("is ".Length);
	}
	// make sure first character is capitalized
	listItemText = Capitalize(listItemText);
	// if only punctuation is left, remove everything
	if (OnlyPunctuationRegex.IsMatch(listItemText)) {
		listItemText = "";
	}
	templateCall = Tools.SetTemplateParameterValue(templateCall, "descrizione", listItemText);
}
private string RemoveValueFromListItemText(string listItemText, string value) {
	listItemText = listItemText.Replace(value, "").Trim();
	listItemText = InvalidDuplicatePunctuationRegex.Replace(listItemText, "$1");
	listItemText = StripLeadingPunctuation(listItemText).Trim();
	return listItemText;
}
// Perform various tasks on listings to ensure params and other values
// are formatted correctly.
public string FormatListings(string articleText, string articleTitle, int wikiNamespace, ref string summary, ref bool skip) {
	string originalText = articleText;
	// loop through all sections
	foreach(KeyValuePair&lt;string, string&gt; sectionData in SplitToSecondLevelSections(articleText)) {
		string sectionName = sectionData.Key;
		string sectionText = sectionData.Value;
		// get all listing tags within the section
		foreach(Match m in ListingTemplateNamesRegex.Matches(sectionText)) {
			string templateCall = m.Value;
			string originalTemplateCall = m.Value;
			templateCall = ConvertGenericListingToSpecificType(templateCall, ref summary);
			templateCall = MatchListingTypeToSection(templateCall, sectionName, ref summary);
			templateCall = FormatListingParams(templateCall, ref summary);
			templateCall = SanitizeListingPhoneNumbers(templateCall, ref summary);
			templateCall = SanitizeListingEmail(templateCall, ref summary);
			templateCall = SanitizeListingUrl(templateCall, ref summary);
			if (AGGRESSIVE) {
				templateCall = SanitizeListingAddress(templateCall, articleTitle, ref summary);
			}
			if (!templateCall.Equals(originalTemplateCall)) {
				articleText = articleText.Replace(originalTemplateCall, templateCall);
			}
		}
	}
	return articleText;
}
// change "{{listing|type=xyz|...}}" to "{{xyz|...}}"
public string ConvertGenericListingToSpecificType(string templateCall, ref string summary) {
	string originalTemplateCall = templateCall;
	string listingType = Tools.GetTemplateName(templateCall);
	if (listingType.Equals("listing")) {
		string templateType = Tools.GetTemplateParameterValue(templateCall, "type");
		if (templateType.Equals("see") || templateType.Equals("do") || templateType.Equals("buy") || templateType.Equals("eat") || templateType.Equals("drink") || templateType.Equals("sleep")) {
			templateCall = Tools.RenameTemplate(templateCall, templateType);
			templateCall = Tools.RemoveTemplateParameter(templateCall, "type");
		}
	}
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "listing appropriato");
	}
	return templateCall;
}
// make sure listings are formatted according to the style guidelines in
// Wikivoyage:Listings
public string FormatListingParams(string templateCall, ref string summary) {
	string originalTemplateCall = templateCall;
	string listingType = Tools.GetTemplateName(templateCall);
	string formattedValue = "{{" + listingType + "\n";
	// loop through expected template arguments and format appropriately
	foreach(string param in ListingTemplateParamNames) {
		if (param.Equals("descrizione")) {
			continue;
		}
		string paramValue = Tools.GetTemplateParameterValue(templateCall, param);
		if (param.Equals("type") &amp;&amp; (paramValue == "" || !listingType.Equals("listing"))) {
			// only listing uses the "type" attribute
			if (paramValue == "") {
				templateCall = Tools.RemoveTemplateParameter(templateCall, param);
			}
			continue;
		}
		if ((param.Equals("image") || param.Equals("lastedit")) &amp;&amp; paramValue == "") {
			// empty image &amp; lastedit attributes are unnecessary
			continue;
		}
		if (listingType.Equals("sleep") &amp;&amp; param.Equals("orari") &amp;&amp; paramValue == "") {
			// sleep listings don't use the "orari" attribute
			if (paramValue == "") {
				templateCall = Tools.RemoveTemplateParameter(templateCall, param);
			}
			continue;
		}
		if (!listingType.Equals("sleep") &amp;&amp; (param.Equals("checkin") || param.Equals("checkout"))) {
			// only sleep listings use the "checkin" and "checkout" attributes
			if (paramValue == "") {
				templateCall = Tools.RemoveTemplateParameter(templateCall, param);
			}
			continue;
		}
		//if (param.Equals("alt") &amp;&amp; paramValue == "" &amp;&amp; !ListingAltParamRegex.IsMatch(templateCall)) {
			// do not add an alt tag if it isn't already present
			//continue;
		//}
		// replace excess whitespace with single spaces
		paramValue = DoubleSpaceRegex.Replace(paramValue, " ");
		formattedValue += "| " + param + "=" + paramValue;
		// add either a newline or a space after the param value, depending on param and template type
		if (param.Equals("email") || param.Equals("indicazioni") || param.Equals("fax") || param.Equals("prezzo") || param.Equals("image") || param.Equals("lastedit")) {
			formattedValue += "\n";
		} else {
			formattedValue += " ";
		}
		templateCall = Tools.RemoveTemplateParameter(templateCall, param);
	}
	// loop through any unexpected template args and format on their own lines
	int remainingTemplateArgs = Tools.GetTemplateArgumentCount(templateCall);
	foreach(KeyValuePair&lt;string, string&gt; templateParameter in Tools.GetTemplateParameterValues(templateCall)) {
		string param = templateParameter.Key;
		if (param.Equals("descrizione")) {
			continue;
		}
		string paramValue = templateParameter.Value;
		if (paramValue == "") {
			// any empty, unrecognized listing params can be removed
			continue;
		}
		formattedValue += "| " + param + "=" + paramValue + "\n";
	}
	// now add template descrizione on its own line
	formattedValue += "| descrizione=" + Tools.GetTemplateParameterValue(templateCall, "descrizione") + "\n";
	formattedValue += "}}";
	if (!originalTemplateCall.Equals(formattedValue)) {
		// suppress edit summary for now - it is being applied to any article with listings
		// whether they are updated or not
		// summary = UpdateEditSummary(summary, "formato listing");
	}
	return formattedValue;
}
// update the listing tel number fields as much as possible to match
// Wikivoyage:Phone numbers
public string SanitizeListingPhoneNumbers(string templateCall, ref string summary) {
	string originalTemplateCall = templateCall;
	// loop through expected template arguments and format appropriately
	foreach(string param in ListingPhoneParamNames) {
		string paramValue = Tools.GetTemplateParameterValue(templateCall, param);
		paramValue = SanitizePhoneNumber(paramValue);
		templateCall = Tools.UpdateTemplateParameterValue(templateCall, param, paramValue);
	}
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "formato phone");
	}
	return templateCall;
}
// update the listing email field to ensure it is valid
public string SanitizeListingEmail(string templateCall, ref string summary) {
	string originalTemplateCall = templateCall;
	string email = Tools.GetTemplateParameterValue(templateCall, "email");
	email = MailtoRegex.Replace(email, "").Trim();
	templateCall = Tools.UpdateTemplateParameterValue(templateCall, "email", email);
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "fix e-mail");
	}
	return templateCall;
}
// update the listing URL field to ensure it is valid
public string SanitizeListingUrl(string templateCall, ref string summary) {
	string originalTemplateCall = templateCall;
	string sito = Tools.GetTemplateParameterValue(templateCall, "sito");
	Match match = FootnoteUrlRegex.Match(sito);
	if (match.Success) {
		sito = match.Groups[1].Value;
	}
	match = ValidUrlRegex.Match(sito);
	if (match.Success &amp;&amp; !sito.ToLower().StartsWith("http://") &amp;&amp; !sito.ToLower().StartsWith("https://") &amp;&amp; !sito.ToLower().StartsWith("//")) {
		sito = "http://" + sito;
	}
	templateCall = Tools.UpdateTemplateParameterValue(templateCall, "sito", sito);
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "sistemo indirizzo web");
	}
	return templateCall;
}
// update the listing indirizzo field to ensure it is valid
public string SanitizeListingAddress(string templateCall, string articleName, ref string summary) {
	string originalTemplateCall = templateCall;
	string indirizzo = Tools.GetTemplateParameterValue(templateCall, "indirizzo");
	if (String.IsNullOrEmpty(indirizzo)) {
		return templateCall;
	}
	Match m = ListingAddressIsDirectionsRegex.Match(indirizzo);
	if (m.Success) {
		// the indirizzo field belongs in the indicazioni field
		string indicazioni = Tools.GetTemplateParameterValue(templateCall, "indicazioni");
		if (String.IsNullOrEmpty(indicazioni)) {
			templateCall = Tools.UpdateTemplateParameterValue(templateCall, "indicazioni", indirizzo);
			templateCall = Tools.UpdateTemplateParameterValue(templateCall, "indirizzo", "");
			summary = UpdateEditSummary(summary, "indicazioni");
			return templateCall;
		}
	}
	// strip out state and zip code if present
	m = AddressWithStateOrZipRegex.Match(indirizzo);
	if (m.Success) {
		indirizzo = m.Groups[1].Value.Trim();
	}
	indirizzo = StripStrayPunctuation(indirizzo);
	// strip out the city if it is present
	string city = GetCityFromArticleName(articleName);
	if (indirizzo.ToLower().EndsWith(city.ToLower())) {
		int pos = indirizzo.ToLower().LastIndexOf(city.ToLower());
		indirizzo = indirizzo.Substring(0, pos).Trim();
	}
	indirizzo = StripStrayPunctuation(indirizzo);
	// properly abbreviate street name
	indirizzo = AbbreviateStreeType(indirizzo, "via", "Via");
	indirizzo = AbbreviateStreeType(indirizzo, "Piazza", "Pz");
	indirizzo = AbbreviateStreeType(indirizzo, "Viale", "V.le");
	indirizzo = AbbreviateStreeType(indirizzo, "Ulica", "Ul");
	indirizzo = AbbreviateStreeType(indirizzo, "Ulitsa", "Ul");
	indirizzo = AbbreviateStreeType(indirizzo, "Uliza", "Ul.");
	indirizzo = AbbreviateStreeType(indirizzo, "Prospekt", "Pr");
	indirizzo = AbbreviateStreeType(indirizzo, "Strasse", "Str");
	indirizzo = AbbreviateStreeType(indirizzo, "Straße", "Str");
	templateCall = Tools.UpdateTemplateParameterValue(templateCall, "indirizzo", indirizzo);
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "indirizzi");
	}
	return templateCall;
}
// make sure that the listing type matches the section in which the listing
// is found (example: "see" listings in the "See" section)
public string MatchListingTypeToSection(string templateCall, string sectionName, ref string summary) {
	string originalTemplateCall = templateCall;
	if (sectionName.ToLower() == "eat and drink" || sectionName.ToLower() == "see and do") {
		// skip these "combined" sections
		return templateCall;
	}
	string expectedListingType = GetValidListingTypeForSection(sectionName);
	string listingType = Tools.GetTemplateName(templateCall);
	if (!listingType.Equals(expectedListingType)) {
		templateCall = Tools.RenameTemplate(templateCall, expectedListingType);
	}
	if (!templateCall.Equals(originalTemplateCall)) {
		summary = UpdateEditSummary(summary, "aggiorno listing");
	}
	return templateCall;
}
// return a map of section name-section descrizione for all second level headings.
// the opening text of the article is returned without a section name
private static List&lt;KeyValuePair&lt;string, string&gt;&gt; SplitToSecondLevelSections(string articleText) {
	List&lt;KeyValuePair&lt;string, string&gt;&gt; sections = new List&lt;KeyValuePair&lt;string, string&gt;&gt;();
	int lastmatchpos = 0;
	Match lastMatch = null;
	foreach(Match m in WikiRegexes.HeadingLevelTwo.Matches(articleText)) {
		if (m.Index &gt; 0) {
			// Don't add empty first section if page starts with heading
			string sectionContent = articleText.Substring(lastmatchpos, m.Index-lastmatchpos);
			string sectionName = (lastMatch != null) ? lastMatch.Groups[1].Value.Trim() : "";
			sections.Add(new KeyValuePair&lt;string, string&gt;(sectionName, sectionContent));
		}
		lastmatchpos = m.Index;
		lastMatch = m;
	}
	// Add text of final section
	string sectionContentLast = articleText.Substring(lastmatchpos);
	string sectionNameLast = (lastMatch != null) ? lastMatch.Groups[1].Value : "";
	sections.Add(new KeyValuePair&lt;string, string&gt;(sectionNameLast, sectionContentLast));
	return sections;
}
// return the expected listing type for the given section name ("See" returns "see").
private static string GetValidListingTypeForSection(string sectionName) {
	if (sectionName == "Cosa vedere") {
		return "see";
	} if (sectionName == "Cosa fare") {
		return "do";
	} if (sectionName == "Acquisti") {
		return "buy";
	} if (sectionName == "Dove mangiare" || sectionName.ToLower() == "Mangiare") {
		return "eat";
	} if (sectionName == "Come divertirsi") {
		return "drink";
	} if (sectionName == "Dove alloggiare") {
		return "sleep";
	} else {
		return "listing";
	}
}
private static string SanitizePhoneNumber(string telNumberText) {
	// strip out the tel number, in case it is contained within other text
	// such as "888-888-8888 (front office)"
	Match match = PhoneNumberRegex.Match(telNumberText);
	if (match.Success) {
		string telNumber = match.Value;
		string originalPhoneNumber = match.Value;
		// remove invalid characters
		telNumber = telNumber.Replace("'", "");
		telNumber = telNumber.Replace("(", " ").Trim();
		telNumber = telNumber.Replace(")", " ").Trim();
		// convert periods to dashes
		telNumber = telNumber.Replace(".", "-");
		telNumber = ExcessWhitespaceRegex.Replace(telNumber, " ");
		// if there is a pattern like " -", "- ", "+ " left, replace the space
		telNumber = telNumber.Replace(" -", "-");
		telNumber = telNumber.Replace("- ", "-");
		telNumber = telNumber.Replace("+ ", "+");
		// if the tel number starts with a 1, change it to +1
		if (telNumber.StartsWith("1 ") || telNumber.StartsWith("1-")) {
			telNumber = "+" + telNumber;
		}
		telNumberText = telNumberText.Replace(originalPhoneNumber, telNumber);
	}
	return telNumberText;
}
// return the city from the article name.  if the article name is "Foo (Disambiguation)"
// then this method returns "Foo".
private static string GetCityFromArticleName(string articleName) {
	string basePageName = Tools.BasePageName(articleName);
	Match match = CityNameWithDisambiguationRegex.Match(basePageName);
	return (match.Success) ? match.Groups[1].Value : basePageName;
}
// if the indirizzo ends in a full street type value, convert to the abbreviated value
private static string AbbreviateStreeType(string indirizzo, string invalidStreetType, string validStreetType) {
	if (indirizzo.ToLower().EndsWith(" " + invalidStreetType.ToLower())) {
		int pos = indirizzo.ToLower().LastIndexOf(invalidStreetType.ToLower());
		if (pos &gt; 0) {
			indirizzo = indirizzo.Substring(0, pos) + validStreetType;
		}
	}
	return indirizzo;
}
// remove any leading or trailing punctuation
private static string StripStrayPunctuation(string text) {
	return StripPunctuation(text, true, true);
}
// remove any leading punctuation
private static string StripLeadingPunctuation(string text) {
	return StripPunctuation(text, true, false);
}
// remove any trailing punctuation
private static string StripTrailingPunctuation(string text) {
	return StripPunctuation(text, false, true);
}
// remove any leading punctuation
private static string StripPunctuation(string text, bool stripLeading, bool stripTrailing) {
	if (stripTrailing) {
		text = InvalidTrailingPunctuationRegex.Replace(text, "");
	}
	if (stripLeading) {
		text = InvalidLeadingPunctuationRegex.Replace(text, "");
	}
	return text;
}
// return true if the text matches the pattern, otherwise return null,  the "match"
// param will be populated with the match object
private static bool MatchText(string matchText, Regex regex, ref Match match) {
	match = regex.Match(matchText);
	return (match.Success);
}
private static string Capitalize(string text) {
	if (String.IsNullOrEmpty(text)) {
		return text;
	}
	// make sure first character is capitalized
	return (text.Length == 1) ? Char.ToUpper(text[0]) + "" : Char.ToUpper(text[0]) + text.Substring(1);
}
// add the value to the edit summary if it is not already present
private static string UpdateEditSummary(string summary, string textToAdd) {
	if (summary == "") {
		return textToAdd;
	}
	foreach(string summaryField in summary.Split(',')) {
		if (summaryField.Trim().Equals(textToAdd)) {
			// text already present in edit summary
			return summary;
		}
	}
	return summary += ", " + textToAdd;
}
// return true if the article contains a city status template
//public static bool IsCityArticle(string articleText) {
//	return CityStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a country status template
//public static bool IsCountryArticle(string articleText) {
//	return CountryStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a dive guide status template
//public static bool IsDiveguideArticle(string articleText) {
//	return DiveguideStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a district status template
//public static bool IsDistrictArticle(string articleText) {
//	return DistrictStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains an itinerary status template
//public static bool IsItineraryArticle(string articleText) {
//	return ItineraryStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a park status template
//public static bool IsParkArticle(string articleText) {
//	return ParkStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a phrasebook status template
//public static bool IsPhrasebookArticle(string articleText) {
//	return PhrasebookStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a region status template
//public static bool IsRegionArticle(string articleText) {
//	return RegionStatusTemplateNamesRegex.IsMatch(articleText);
//}
// return true if the article contains a topic status template
//public static bool IsTopicArticle(string articleText) {
//	return TopicStatusTemplateNamesRegex.IsMatch(articleText);
//}
// TODO:
// - clean up frontlink conversion logic
// - move tollfree numbers to tollfree in listings
// - don't allow "otheruses" to be moved above the page banner</Code>
  </Module>
  <ExternalProgram>
    <Enabled>false</Enabled>
    <Skip>false</Skip>
    <Program />
    <Parameters />
    <PassAsFile>true</PassAsFile>
    <OutputFile />
  </ExternalProgram>
  <Disambiguation>
    <Enabled>false</Enabled>
    <Link />
    <Variants />
    <ContextChars>20</ContextChars>
  </Disambiguation>
  <Special>
    <namespaceValues>
      <int>0</int>
      <int>1</int>
      <int>2</int>
      <int>3</int>
      <int>4</int>
      <int>5</int>
      <int>6</int>
      <int>7</int>
      <int>10</int>
      <int>11</int>
      <int>14</int>
      <int>15</int>
    </namespaceValues>
    <remDupes>true</remDupes>
    <sortAZ>true</sortAZ>
    <filterTitlesThatContain>false</filterTitlesThatContain>
    <filterTitlesThatContainText />
    <filterTitlesThatDontContain>false</filterTitlesThatDontContain>
    <filterTitlesThatDontContainText />
    <areRegex>false</areRegex>
    <opType>-1</opType>
    <remove />
  </Special>
  <Tool>
    <ListComparerUseCurrentArticleList>0</ListComparerUseCurrentArticleList>
    <ListSplitterUseCurrentArticleList>0</ListSplitterUseCurrentArticleList>
    <DatabaseScannerUseCurrentArticleList>0</DatabaseScannerUseCurrentArticleList>
  </Tool>
  <Plugin />
</AutoWikiBrowserPreferences>


Eseguire modifiche con AWB[modifica]

Per operare modifiche con AWB è necessario innanzitutto individuare un elenco di articoli da editare. Una volta fatto, AWB creerà una lista in un riquadro al lato sinistro della sua interfaccia e di volta in volta mostrerà il Diff di ogni modifica. Per iniziare ad operare con AWB clicca su Start (ultima linguetta del riquadro centrale) e poi ancora sul pulsante Start. AWB visualizzerà il testo con le modifiche che intende apportare e un riquadro con diverse opzioni, comprese quelle di modifica manuale. Per non effettuare alcuna modifica premi Skip, per salvarla fai clic su Save.

  • Attenzione: AWB potrebbe apportare modifiche diverse da quelle attese, in quanto si basa su espressioni regolari, e spetta a voi per rivedere le modifiche proposte e correggere eventuali errori prima di salvare. La responsabilità di ogni modifica è solo vostra.

Modifiche manuali possono essere effettuate modificando il contenuto della scheda "Edit". Una volta salvata una modifica questa apparirà nella cronologia della relativa pagina. In ogni caso, appena salvato o saltato un diff, AWB procederà con le successive pagine nella lista.

Creare la lista[modifica]

Vai nel riquadro "Source" e digitare il nome dell'articolo da modificare o una modalità di creazione della lista, quindi utilizza "Make list" per le diverse opzioni o per generare la lista pronta all'utilizzo.

Mi sembra di aver capito, ma...

1328102026 Anouncement.png
Se pensi che sia proprio troppo difficile o che non riesci ad afferrare qualche concetto o che non capisci il perché di tale procedura, ci metti cinque secondi a chiederlo e avere risposta; se pensi poi di avere una proposta, piccola o grande che sia, siamo tutti pronti ad ascoltarti.

L'elenco di tutte le pagine riguardanti Wikivoyage si trova nella pagina Aiuto:Aiuto.