Rosetta Code/Find bare lang tags: Difference between revisions

m
(→‎{{header|Wren}}: Removed superfluous line.)
m (→‎{{header|Wren}}: Minor tidy)
 
(7 intermediate revisions by 5 users not shown)
Line 39:
 
;Extra extra credit:
Use the   [http://rosettacode.org/[mw/api.php :API:Main_page|Media Wiki API]]   to test actual RC tasks.
<br><br>
 
Line 75:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang=Erlang>
-module( find_bare_lang_tags ).
 
Line 104:
Stop = string:rstr( Line, "}}==" ),
string:sub_string( Line, Start+1, Stop-1 ).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 114:
 
=={{header|Go}}==
<langsyntaxhighlight lang=go>package main
 
import (
Line 212:
fmt.Printf(" %d in %-11s %v\n", v.count, k, *v.names)
}
}</langsyntaxhighlight>
 
{{out}}
Line 257:
=={{header|Groovy}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang=groovy>import java.util.function.Predicate
import java.util.regex.Matcher
import java.util.regex.Pattern
Line 312:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>2 in Scilab
Line 329:
This solution can be compiled into a program that will either take space-delimited list of files as its argument, or take input from STDIN if no arguments are provided. Additionally, if you specify the -w flag in the first argument, it will take a list of Rosetta Code wiki pages and search them. Note that the page names must be as they appear in your URL bar -- underscores in place of spaces.
 
<langsyntaxhighlight lang=Haskell>import System.Environment
import Network.HTTP
import Text.Printf
Line 408:
response <- simpleHTTP.getRequest$ url
getResponseBody response
where url = "http://rosettacode.org/mw/index.php?action=raw&title="++title</langsyntaxhighlight>
 
Here are the input files I used to test:
Line 470:
 
The following is a Unicon-specific solution.
<langsyntaxhighlight lang=unicon>import Utils # To get the FindFirst class
 
procedure main()
Line 488:
write(total," bare language tags:\n")
every pair := !sort(tags) do write(pair[2]," in ",pair[1])
end</langsyntaxhighlight>
 
Sample run using example given in problem statement:
Line 501:
 
=={{header|Java}}==
<langsyntaxhighlight lang=java>import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
Line 562:
}
}
}</langsyntaxhighlight>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq.'''
 
'''Adapted from [[#Wren|Wren]]'''
<syntaxhighlight lang=jq>
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
def trim: sub("^[ \t]+";"") | sub("[ \t]+$";"");
 
# Insert into a sorted list using bsearch
def binsert($x):
(-bsearch($x) - 1) as $ix
| if $ix < 0 then .
else .[:$ix] + [$x] + .[$ix:]
end;
 
def report:
def header:
"==\\s*{{\\s*header\\s*\\|\\s*(?<title>[^\\s\\}]+)\\s*}}\\s*==";
 
reduce inputs as $line ( { bareCount:0, bareLang: {} };
if .fileName != input_filename
then .lastHeader = "No language"
| .fileName = input_filename
else .
end
| .line = ($line|trim)
| if .line | length == 0 then .
else .header = ((.line | capture(header)) // null)
| if .header
then .lastHeader = .header.title
elif .line|startswith("<lang>")
then .bareCount += 1
| .bareLang[.lastHeader][0] += 1
| .fileName as $fileName
| .bareLang[.lastHeader][1] |= binsert($fileName)
else .
end
end )
| "\(.bareCount) bare language tags:",
(.bareLang
| to_entries[] as {"key": $lang, "value": $value}
| $value[0] as $count
| $value[1] as $names
| ("\($count|lpad(3)) in \($lang|lpad(15))" + ": " + ($names | join(", ")) )) ;
 
report
</syntaxhighlight>
'''Invocation'''
 
Using the examples in the [[#Go|Go]] entry:
<pre>
jq -Rnr -f find-bare-lang-tags.jq rc-example1.txt rc-example2.txt
rc-example3.txt
</pre>
{{output}}
<pre>
5 bare language tags:
2 in No language: rc-example1.txt, rc-example3.txt
1 in Perl: rc-example1.txt
2 in C: rc-example2.txt, rc-example3.txt
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang=julia>using Gumbo, AbstractTrees, HTTP, JSON, Dates
 
rosorg = "http://rosettacode.org"
Line 652 ⟶ 716:
println("\nDraft programming tasks:")
qdURI |> getpages |> processtaskpages
</langsyntaxhighlight>{{out}}
<pre>
Programming examples at 2019-02-19T06:33:49.951:
Line 766 ⟶ 830:
Total bare <lang> for language zkl: 2
Total bare <lang> for language zonnon: 1
Total bare <lang> for language МК??-61/52: 62
 
Draft programming tasks:
Line 781 ⟶ 845:
Total bare <lang> for language Racket: 1
Total bare <lang> for language uBasic/4tH: 1
Total bare <lang> for language МК??-61/52: 2
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang=scala>import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
Line 843 ⟶ 907:
println("Got a ${titleResponse.statusCode()} status code")
}
}</langsyntaxhighlight>
{{out}}
<pre>1 in 4DOS Batch
Line 856 ⟶ 920:
 
=={{header|Maple}}==
<langsyntaxhighlight lang=Maple>#Did not count the tasks where languages tasks are properly closed
add_lan := proc(language, n, existence, languages, pos)
if (assigned(existence[language])) then
Line 923 ⟶ 987:
end do:
printf("Total number %d", total);
</syntaxhighlight>
</lang>
{{Out|Output}}
<pre>15 Puzzle Game is not counted since some language tags are not properly closed.
Line 938 ⟶ 1,002:
There are 3 bare lang tags in PicoLisp
There are 15 bare lang tags in CoffeeScript
There are 29 bare lang tags in МК??-61/52
There are 2 bare lang tags in APL
There are 10 bare lang tags in ERRE
Line 1,033 ⟶ 1,097:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight lang="Mathematica">tasks[page_: ""] :=
Module[{res =
Import["http://rosettacode.org/mw/api.php?format=xml&action=\
Line 1,063 ⟶ 1,127:
Function[task, MemberQ[task[[2]], # -> _Integer?Positive]]]],
"]], [["] <> "]])"] & @@@
Select[SortBy[langCounts, Keys], #[[2]] > 0 &];</langsyntaxhighlight>
This script looks for all of the pages in [[:Category:Programming Tasks]], downloads them, and gets the bare tags per language. Then, it gets the total of all of them, prints it, and sums up the bare tags by language. Note that it doesn't check if the tags are in a block or even closed, so it picks up false positives (especially on this page.)
{{out}}
Line 1,071 ⟶ 1,135:
1 in 360 Assembly ([[FizzBuzz]])
1 in 4DOS Batch ([[100 doors]])
71 in МК??-61/52 ([[Arithmetic-geometric mean]], [[Arithmetic-geometric mean/Calculate Pi]], [[Arithmetic/Complex]], [[Arithmetic/Integer]], [[Averages/Arithmetic mean]], [[Averages/Root mean square]], [[Balanced ternary]], [[Circles of given radius through two points]], [[Combinations and permutations]], [[Conditional structures]], [[Convert decimal number to rational]], [[Count in octal]], [[Day of the week]], [[Dot product]], [[Empty program]], [[Ethiopian multiplication]], [[Euler method]], [[Evaluate binomial coefficients]], [[Even or odd]], [[Execute a Markov algorithm]], [[Exponentiation operator]], [[Fibonacci sequence]], [[Find limit of recursion]], [[Greatest element of a list]], [[Haversine formula]], [[Higher-order functions]], [[Holidays related to Easter]], [[Horizontal sundial calculations]], [[Horner's rule for polynomial evaluation]], [[Integer comparison]], [[Integer sequence]], [[Jump anywhere]], [[Leap year]], [[Least common multiple]], [[Loops/Break]], [[Loops/Do-while]], [[Loops/Downward for]], [[Loops/For with a specified step]], [[Loops/Infinite]], [[Loops/While]], [[Main step of GOST 28147-89]], [[Middle three digits]], [[Modular inverse]], [[Monte Carlo methods]], [[Multifactorial]], [[Multiplication tables]], [[Nth root]], [[Pick random element]], [[Polynomial regression]], [[Primality by trial division]], [[Program termination]], [[Random numbers]], [[Real constants and functions]], [[Roots of a quadratic function]], [[Roots of unity]], [[Sequence of non-squares]], [[Standard deviation]], [[Sum and product of an array]], [[Sum digits of an integer]], [[Sum multiples of 3 and 5]], [[Sum of squares]], [[Ternary logic]], [[Towers of Hanoi]], [[Vector products]], [[Voronoi diagram]], [[Zero to the zero power]])
2 in 6502 Assembly ([[FizzBuzz]], [[String case]])
2 in 6800 Assembly ([[Hello world/Text]], [[Loops/Infinite]])
Line 1,180 ⟶ 1,244:
=={{header|Nim}}==
{{trans|Julia}}
<langsyntaxhighlight lang=Nim>import algorithm, htmlparser, httpclient, json
import sequtils, strformat, strscans, tables, times, xmltree
import strutils except escape
Line 1,252 ⟶ 1,316:
 
echo "\nDraft programming tasks:"
client.processTaskPages(client.getPages(QdUri))</langsyntaxhighlight>
 
{{out}}
Line 1,308 ⟶ 1,372:
=={{header|Objeck}}==
With extra credit
<langsyntaxhighlight lang=objeck>use Web.HTTP;
use Query.RegEx;
use Collection.Generic;
Line 1,402 ⟶ 1,466:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,436 ⟶ 1,500:
=={{header|Perl}}==
This is a simple implementation that does not attempt either extra credit.
<langsyntaxhighlight lang=perl>my $lang = 'no language';
my $total = 0;
my %blanks = ();
Line 1,457 ⟶ 1,521:
print "$k in $v\n"
}
}</langsyntaxhighlight>
 
=={{header|Phix}}==
Both extra credits. Would probably benefit from excluding &lt;pre&gt;&lt;/pre&gt; sections first.
<!--<lang Phix>(notonline)-->
<lang Phix>-- demo\rosetta\Find_bare_lang_tags.exw
<span style="color: #000080;font-style:italic;">--
--
-- demo\rosetta\Find_bare_lang_tags.exw
-- Finds/counts no of "<lang>" as opposed to eg "<lang Phix>" tags.
-- ====================================
-- Since downloading all the pages can be very slow, this uses a cache.
--
-- (Uses '&' instead of/as well as 'a', for everyone's sanity..)
constant include_drafts = true,
-- Finds/counts no of "&lt;l&ng&gt;" as opposed to eg "&lt;l&ng Phix&gt;" tags.
sort_by_task = false,
-- Since downloading all the pages can be very slow, this uses a cache.
sort_by_lang = not sort_by_task -- (one or t'other)
--</span>
 
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (fairly obviously this will never ever run in a browser!)</span>
integer lp = 0
<span style="color: #008080;">constant</span> <span style="color: #000000;">include_drafts</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">,</span>
procedure progress(string msg, sequence args = {})
<span style="color: #000000;">sort_by_task</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">,</span>
if length(args) then msg = sprintf(msg,args) end if
<span style="color: #000000;">sort_by_lang</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">not</span> <span style="color: #000000;">sort_by_task</span> <span style="color: #000080;font-style:italic;">-- (one or t'other)</span>
integer lm = length(msg)
if lm<lp then msg[$..$] = repeat(' ',lp-lm)&msg[$] end if
<span style="color: #008080;">include</span> <span style="color: #000000;">rosettacode_cache</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- see [[Rosetta_Code/Count_examples#Phix]]</span>
puts(1,msg)
lp = iff(msg[$]='\r'?lm:0)
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">utf8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ansi</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">x"E28093"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">},</span>
end procedure
<span style="color: #0000FF;">{</span><span style="color: #008000;">x"E28099"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"'"</span><span style="color: #0000FF;">},</span>
 
<span style="color: #0000FF;">{</span><span style="color: #008000;">x"C3A8"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"e"</span><span style="color: #0000FF;">},</span>
include builtins\timedate.e
<span style="color: #0000FF;">{</span><span style="color: #008000;">x"C3A9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"e"</span><span style="color: #0000FF;">},</span>
integer refresh_cache = timedelta(days:=365) -- 0 for always
<span style="color: #0000FF;">{</span><span style="color: #008000;">x"D09A"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"K"</span><span style="color: #0000FF;">},</span>
--integer refresh_cache = timedelta(days:=1) -- 0 for always
<span style="color: #0000FF;">{</span><span style="color: #008000;">x"D09C"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"M"</span><span style="color: #0000FF;">}})</span>
 
include builtins\libcurl.e
<span style="color: #008080;">function</span> <span style="color: #000000;">utf8_clean</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
atom curl = NULL
<span style="color: #008080;">return</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">utf8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ansi</span><span style="color: #0000FF;">)</span>
atom pErrorBuffer
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function write_callback(atom pData, integer size, integer nmemb, integer fn)
<span style="color: #008080;">function</span> <span style="color: #000000;">multi_lang</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
integer bytes_written = size * nmemb
<span style="color: #000080;font-style:italic;">-- Convert eg {"Algol","Algol","C","C","C"} to "Algol[2],C[3]"</span>
puts(fn,peek({pData,bytes_written}))
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
return bytes_written
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end function
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
constant write_cb = call_back({'+', routine_id("write_callback")})
<span style="color: #008080;">while</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">+=</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
 
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s[%d]"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})}</span>
function open_download(string filename, url)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
bool refetch = true
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
if get_file_type("rc_cache")!=FILETYPE_DIRECTORY then
<span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
if not create_directory("rc_cache") then
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
crash("cannot create rc_cache directory")
<span style="color: #008080;">return</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end if
filename = join_path({"rc_cache",filename})
<span style="color: #008080;">function</span> <span style="color: #000000;">multi_task</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tasks</span><span style="color: #0000FF;">)</span>
if file_exists(filename) then
<span style="color: #000080;font-style:italic;">-- Similar to multi_lang() but with task[indexes]</span>
-- use existing file if <= refresh_cache (365 days) old
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
sequence last_mod = get_file_date(filename) -- (0.8.1+)
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
atom delta = timedate_diff(last_mod,date())
<span style="color: #004080;">integer</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
refetch = (delta>refresh_cache) or get_file_size(filename)=0
<span style="color: #004080;">string</span> <span style="color: #000000;">tsi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">html_clean</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">si</span><span style="color: #0000FF;">])</span>
else
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
string directory = get_file_path(filename)
<span style="color: #008080;">while</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">+=</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if get_file_type(directory)!=FILETYPE_DIRECTORY then
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s[%d]"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tsi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})}</span>
if not create_directory(directory,make_parent:=true) then
<span style="color: #008080;">else</span>
crash("cannot create %s directory",{directory})
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tsi</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
object text
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if not refetch then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)></span><span style="color: #000000;">8</span> <span style="color: #008080;">then</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"..."</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
text = trim(get_text(filename))
<span style="color: #008080;">return</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)</span>
refetch = (not sequence(text)) or (length(text)<10)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end if
if refetch then
<span style="color: #004080;">bool</span> <span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
progress("Downloading %s...\r",{filename})
if curl=NULL then
<span style="color: #008080;">function</span> <span style="color: #000000;">find_bare_lang_tags</span><span style="color: #0000FF;">()</span>
curl_global_init()
<span style="color: #008080;">if</span> <span style="color: #7060A8;">get_file_type</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rc_cache"</span><span style="color: #0000FF;">)!=</span><span style="color: #004600;">FILETYPE_DIRECTORY</span> <span style="color: #008080;">then</span>
curl = curl_easy_init()
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">create_directory</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rc_cache"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
pErrorBuffer = allocate(CURL_ERROR_SIZE)
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"cannot create rc_cache directory"</span><span style="color: #0000FF;">)</span>
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, pErrorBuffer)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #000080;font-style:italic;">-- note this lot use web scraping (as cribbed from a similar task) ...</span>
url = substitute(url,"%3A",":")
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tasks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dewiki</span><span style="color: #0000FF;">(</span><span style="color: #000000;">open_category</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Programming_Tasks"</span><span style="color: #0000FF;">))</span>
url = substitute(url,"%2A","*")
<span style="color: #008080;">if</span> <span style="color: #000000;">include_drafts</span> <span style="color: #008080;">then</span>
curl_easy_setopt(curl, CURLOPT_URL, url)
<span style="color: #000000;">tasks</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">dewiki</span><span style="color: #0000FF;">(</span><span style="color: #000000;">open_category</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Draft_Programming_Tasks"</span><span style="color: #0000FF;">))</span>
integer fn = open(filename,"wb")
<span style="color: #000000;">tasks</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">)</span>
if fn=-1 then ?9/0 end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fn)
<span style="color: #004080;">integer</span> <span style="color: #000000;">blt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Rosetta_Code/Find_bare_lang_tags"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- not this one!</span>
while true do
<span style="color: #000000;">tasks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">blt</span><span style="color: #0000FF;">..</span><span style="color: #000000;">blt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
CURLcode res = curl_easy_perform(curl)
if res=CURLE_OK then exit end if
<span style="color: #000080;font-style:italic;">-- ... whereas the individual tasks use the web api instead (3x smaller/faster)</span>
string error = sprintf("%d",res)
<span style="color: #004080;">integer</span> <span style="color: #000000;">total_count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
if res=CURLE_COULDNT_RESOLVE_HOST then
<span style="color: #000000;">lt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">),</span>
error &= " [CURLE_COULDNT_RESOLVE_HOST]"
<span style="color: #000000;">kept</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
end if
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d tasks found\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">})</span>
progress("Error %s downloading file, retry?(Y/N):",{error})
<span style="color: #004080;">sequence</span> <span style="color: #000000;">task_langs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
if lower(wait_key())!='y' then abort(0) end if
<span style="color: #000000;">task_counts</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sort_by_task</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">):{}),</span>
printf(1,"Y\n")
<span style="color: #000000;">task_things</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sort_by_task</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">):{})</span>
end while
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
close(fn)
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tasks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
refresh_cache += timedelta(days:=1) -- did I mention it is slow?
<span style="color: #000000;">url</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"http://rosettacode.org/mw/index.php?title=%s&action=raw"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">}),</span>
text = get_text(filename)
<span style="color: #000000;">contents</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_download</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">&</span><span style="color: #008000;">".raw"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">url</span><span style="color: #0000FF;">),</span>
end if
<span style="color: #000000;">curr</span>
return text
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">start</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">header</span>
end function
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
 
<span style="color: #000000;">start</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`&lt;l`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`ang&gt;`</span><span style="color: #0000FF;">,</span><span style="color: #000000;">contents</span><span style="color: #0000FF;">,</span><span style="color: #000000;">start</span><span style="color: #0000FF;">)</span>
function open_category(string filename)
<span style="color: #008080;">if</span> <span style="color: #000000;">start</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return open_download(filename&".htm","http://rosettacode.org/wiki/Category:"&filename)
<span style="color: #000080;font-style:italic;">-- look backward for the nearest header</span>
end function
<span style="color: #000000;">header</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rmatch</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`{he`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`ader|`</span><span style="color: #0000FF;">,</span><span style="color: #000000;">contents</span><span style="color: #0000FF;">,</span><span style="color: #000000;">start</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">if</span> <span style="color: #000000;">header</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
function dewiki(string s)
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"no language"</span>
-- extract tasks from eg `<li><a href="/wiki/100_doors"`
<span style="color: #008080;">else</span>
sequence tasks = {}
<span style="color: #000000;">header</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`{he`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`ader|`</span><span style="color: #0000FF;">)</span>
integer start = 1, finish = match(`<div class="printfooter">`,s)
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">utf8_clean</span><span style="color: #0000FF;">(</span><span style="color: #000000;">contents</span><span style="color: #0000FF;">[</span><span style="color: #000000;">header</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`<nowiki>}}</nowiki>`</span><span style="color: #0000FF;">,</span><span style="color: #000000;">contents</span><span style="color: #0000FF;">,</span><span style="color: #000000;">header</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
s = s[1..finish-1]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
while true do
<span style="color: #008080;">if</span> <span style="color: #000000;">sort_by_lang</span> <span style="color: #008080;">then</span>
start = match("<li><a href=\"/wiki/",s,start)
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">task_langs</span><span style="color: #0000FF;">)</span>
if start=0 then exit end if
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
start += length("<li><a href=\"/wiki/")
<span style="color: #000000;">task_langs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_langs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">)</span>
finish = find('"',s,start)
<span style="color: #000000;">task_things</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_things</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
string task = s[start..finish-1]
<span style="color: #000000;">task_counts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_counts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
task = substitute_all(task,{"*",":"},{"%2A","%3A"})
<span style="color: #008080;">else</span>
if task!="Rosetta_Code/Find_bare_lang_tags" then -- not this one!
<span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
tasks = append(tasks,task)
<span style="color: #000000;">task_counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- if length(tasks)>10 then exit end if -- (debug aid)
<span style="color: #008080;">else</span>
start = finish+1
<span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return tasks
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end function
<span style="color: #000000;">start</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`&lt;l`</span><span style="color: #0000FF;">&</span><span style="color: #008000;">`ang&gt;`</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
constant {html,ascii} = columnize({{"%2A","*"},
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
{"%3A",":"},
<span style="color: #008080;">if</span> <span style="color: #000000;">sort_by_task</span> <span style="color: #008080;">then</span>
{"%27","'"},
<span style="color: #000000;">task_counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">count</span>
{"%2B","+"},
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{"%22","\""},
<span style="color: #000000;">kept</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
{"%E2%80%93","-"},
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{"%E2%80%99","'"},
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d tasks kept, %d to go\r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">kept</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
{"%C3%A8","e"},
<span style="color: #000000;">total_count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">count</span>
{"%C3%A9","e"}})
<span style="color: #008080;">if</span> <span style="color: #7060A8;">get_key</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">#1B</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"escape keyed\n"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
function html_clean(string s)
<span style="color: #000000;">curl_cleanup</span><span style="color: #0000FF;">()</span>
return substitute_all(s,html,ascii)
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d tasks with bare lang tags\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">kept</span><span style="color: #0000FF;">})</span>
end function
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_counts</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_counts</span><span style="color: #0000FF;">)))</span>
 
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
constant {utf8,ansi} = columnize({{x"E28093","-"},
<span style="color: #004080;">integer</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
{x"E28099","'"},
<span style="color: #000000;">tc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">task_counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">]</span>
{x"C3A8","e"},
<span style="color: #008080;">if</span> <span style="color: #000000;">tc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{x"C3A9","e"},
<span style="color: #008080;">if</span> <span style="color: #000000;">sort_by_task</span> <span style="color: #008080;">then</span>
{x"D09A","K"},
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s %d (%s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">html_clean</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">]),</span><span style="color: #000000;">tc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">multi_lang</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">])})</span>
{x"D09C","M"}})
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- (sort_by_count)</span>
 
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s %d (%s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">task_langs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">],</span><span style="color: #000000;">tc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">multi_task</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_things</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">],</span><span style="color: #000000;">tasks</span><span style="color: #0000FF;">)})</span>
function utf8_clean(string s)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return substitute_all(s,utf8,ansi)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">total_count</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function multi_lang(sequence s)
-- Convert eg {"Algol","Algol","C","C","C"} to "Algol[2],C[3]"
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Total: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">find_bare_lang_tags</span><span style="color: #0000FF;">()})</span>
integer i = 1, j = 2
while i<length(s) do
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
if s[i]=s[j] then
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
while j<length(s) and s[i]=s[j+1] do j+=1 end while
<!--</lang>-->
s[i..j] = {sprintf("%s[%d]",{s[i],j-i+1})}
end if
i += 1
j = i+1
end while
return join(s,",")
end function
 
function multi_task(sequence s, tasks)
-- Similar to multi_lang() but with task[indexes]
integer i = 1, j = 2
while i<=length(s) do
integer si = s[i]
string tsi = html_clean(tasks[si])
if j<=length(s) and si=s[j] then
while j<length(s) and si=s[j+1] do j+=1 end while
s[i..j] = {sprintf("%s[%d]",{tsi,j-i+1})}
else
s[i] = tsi
end if
i += 1
j = i+1
end while
if length(s)>8 then s[4..-4] = {"..."} end if
return join(s,",")
end function
 
function find_bare_lang_tags()
-- note this lot use web scraping (as cribbed from a similar task) ...
sequence tasks = dewiki(open_category("Programming_Tasks"))
if include_drafts then
tasks &= dewiki(open_category("Draft_Programming_Tasks"))
tasks = sort(tasks)
end if
-- ... whereas the individual tasks use the web api instead (3x smaller/faster)
integer total_count = 0,
lt = length(tasks),
kept = 0
progress("%d tasks found\n",{lt})
sequence task_langs = {},
task_counts = iff(sort_by_task?repeat(0,lt):{}),
task_things = iff(sort_by_task?repeat({},lt):{})
for i=1 to length(tasks) do
string ti = tasks[i],
url = sprintf("http://rosettacode.org/mw/index.php?title=%s&action=raw",{ti}),
contents = open_download(ti&".raw",url),
this
integer count = 0, start = 1, header
while true do
start = match(`<lang>`,contents,start)
if start=0 then exit end if
-- look backward for the nearest header
header = rmatch(`{{header|`,contents,start)
if header=0 then
-- this = ""
this = "no language"
else
header += length(`{{header|`)
this = utf8_clean(contents[header..match(`}}`,contents,header)-1])
end if
if sort_by_lang then
integer k = find(this,task_langs)
if k=0 then
task_langs = append(task_langs,this)
task_things = append(task_things,{i})
task_counts = append(task_counts,1)
else
task_things[k] = append(task_things[k],i)
task_counts[k] += 1
end if
else
task_things[i] = append(task_things[i],this)
end if
count += 1
start += length(`<lang>`)
end while
if count!=0 then
if sort_by_task then
task_counts[i] = count
end if
kept += 1
end if
progress("%d tasks kept, %d to go\r",{kept,lt-i})
total_count += count
if get_key()=#1B then progress("escape keyed\n") exit end if
end for
if curl!=NULL then
curl_easy_cleanup(curl)
free(pErrorBuffer)
curl = NULL
pErrorBuffer = NULL
end if
progress("%d tasks with bare lang tags\n",{kept})
sequence tags = custom_sort(task_counts,tagset(length(task_counts)))
for i=length(tags) to 1 by -1 do
integer ti = tags[i],
tc = task_counts[ti]
if tc=0 then exit end if
--if tc>5 then
if sort_by_task then
progress("%s %d (%s)\n",{html_clean(tasks[ti]),tc,multi_lang(task_things[ti])})
else -- (sort_by_count)
progress("%s %d (%s)\n",{task_langs[ti],tc,multi_task(task_things[ti],tasks)})
end if
--end if
end for
return total_count
end function
 
progress("Total: %d\n",{find_bare_lang_tags()})</lang>
{{out}}
as of 26/7/19, sort_by_task:
Line 1,749 ⟶ 1,704:
 
=={{header|Python}}==
<langsyntaxhighlight lang=python>
"""Count bare `lang` tags in wiki markup. Requires Python >=3.6.
 
Line 2,062 ⟶ 2,017:
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.DEBUG)
example()
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,090 ⟶ 2,045:
1 in Python ['Abelian sandpile model']
1 in GFA Basic ['Abundant, deficient and perfect number classifications']
1 in МК??-61/52 ['Ackermann function']
1 in Nim ['Active object']
1 in Go ['Address of a variable']
Line 2,101 ⟶ 2,056:
Note that this follows the task, but the output is completely bogus since the actual <tt>&lt;lang&gt;</tt> tags that it finds are in <tt>&lt;pre&gt;</tt> and in code...
 
<langsyntaxhighlight lang=racket>
#lang racket
 
Line 2,130 ⟶ 2,085:
 
(find-bare-tags "Rosetta Code/Find bare lang tags")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,142 ⟶ 2,097:
===More-extra credit===
Add the following code at the bottom, run, watch results.
<langsyntaxhighlight lang=racket>
(define (get-category cat)
(let loop ([c #f])
Line 2,159 ⟶ 2,114:
(printf "Page: ~a " page)
(find-bare-tags page))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 2,165 ⟶ 2,120:
{{trans|Perl}}
The only tricky thing here is the use of the <tt>ms</tt> form of match, short for <tt>m:sigspace</tt>. This causes whitespace in the regex to be considered "significant", that is, it matches optional whitespace at those positions, as if you'd put <tt>\s*</tt> there. Of course, the regexes themselves are in Raku syntax, which is quite different from Perl 5 regex syntax (and arguably much cleaner). Regex syntax is perhaps the area in which Raku diverges most from Perl 5.
<syntaxhighlight lang="raku" perl6line>my $lang = '(no language)';
my $total = 0;
my %blanks;
Line 2,180 ⟶ 2,135:
 
say "$total bare language tag{ 's' if $total != 1 }\n";
say .value, ' in ', .key for %blanks.sort;</langsyntaxhighlight>
{{out}}
<pre>2 bare language tags
Line 2,188 ⟶ 2,143:
 
=={{header|REXX}}==
<langsyntaxhighlight lang=rexx>/*REXX pgm finds and displays bare language (<lang>) tags without a language specified. */
parse arg iFID . /*obtain optional argument from the CL.*/
if iFID=='' | iFID="," then iFID= 'BARELANG.HTM' /*Not specified? Then assume default*/
Line 2,199 ⟶ 2,154:
$= space($) /*elide superfluous blanks from record.*/
if $=='' then iterate /*if a blank line, then skip any tests.*/
call testHead /*process possible ==((header|αααaaa}}== */
call testLang /* " " <lang αααaaa> or <lang>*/
end /*recs*/
 
Line 2,207 ⟶ 2,162:
if bare==0 then bare= 'no'; say right(bare, 9) " bare language tags."; say
 
do #=1 for words(head); _= word(head, #) /*maybe show <lang> for language αααaaa */
if !._\==0 then say right(!._, 9) ' in' _ /*show the count for a particular lang.*/
end /*#*/
Line 2,213 ⟶ 2,168:
if noLa==0 then noLa= 'no'; say right(noLa, 9) " in no specified language."
exit 0
/*--------------------------------------------------------------------------------------*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
testHead: @head= '=={{header|'; @foot= "}}==" /*define two literals. */
hh= pos(@head, $ ); if hh==0 then return /*get start of literal.*/
Line 2,220 ⟶ 2,175:
head= substr($, or+1, hb-or-1) /*get the language name*/
if head\=='' then header= head /*Header? Then use it.*/
if wordpos(head, heads)==0 then heads= heads head /*Is lang? Add──►Add--? list*/
return
/*--------------------------------------------------------------------------------------*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
testLang: @lang= '<lang'; @back= ">" /*define two literals. */
s1= pos(@lang, $ ); if s1==0 then return /*get start of literal.*/
Line 2,231 ⟶ 2,186:
if @lang\=='' & header=='' then noLa= noLa + 1 /*bump noLang counter.*/
if @lang\=='' & header\=='' then !.head= !.head + 1 /*bump a lang " */
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 2,244 ⟶ 2,199:
=={{header|Ruby}}==
Quoting from the FAQ: "If you just want the raw wikitext without any other information whatsoever, it's best to use index.php's action=raw mode instead of the API"
<langsyntaxhighlight lang=Ruby>require "open-uri"
require "cgi"
 
Line 2,266 ⟶ 2,221:
 
puts "\n#{result.values.map(&:count).inject(&:+)} bare language tags.\n\n"
result.each{|k,v| puts "#{v.count} in #{k} (#{v.tasks})"}</langsyntaxhighlight>
{{Output}}
<pre>
Line 2,278 ⟶ 2,233:
1 in gnuplot (["Greatest_common_divisor"])
1 in Bracmat (["Greatest_element_of_a_list"])
2 in МК??-61/52 (["Greatest_element_of_a_list", "Greatest_element_of_a_list"])
1 in ooRexx (["Greatest_element_of_a_list"])
2 in Mathprog (["Greatest_subsequential_sum", "Greatest_subsequential_sum"])
Line 2,285 ⟶ 2,240:
 
=={{header|Rust}}==
<langsyntaxhighlight lang=rust>
extern crate regex;
 
Line 2,341 ⟶ 2,296:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,348 ⟶ 2,303:
=={{header|Scala}}==
To analyse RosettaCode pages, invoke Java with <code>-Dhttp.agent=Anything</code> to work around CloudFlare blocking Java from accessing the RosettaCode site.
<langsyntaxhighlight lang=Scala>// Map lines to a list of Option(heading -> task) for each bare lang tag found.
val headerFormat = "==[{]+header[|]([^}]*)[}]+==".r
val langFormat = "<lang([^>]*)>".r
Line 2,380 ⟶ 2,335:
def summary = format(mapReduce) mkString "\n"
}
def mapReduce(inputs: Seq[BareLangFinder]) = reduced(inputs.flatMap(_.map))</langsyntaxhighlight>
'''Examples:'''
<pre>val test = """
Line 2,411 ⟶ 2,366:
2 in Mathprog (Greatest_subsequential_sum)
1 in gnuplot (Greatest_common_divisor)
2 in МК??-61/52 (Greatest_element_of_a_list)
1 in Bracmat (Greatest_element_of_a_list)
1 in PHP (Greatest_subsequential_sum)
Line 2,422 ⟶ 2,377:
{{tcllib|textutil::split}}
{{tcllib|uri}}
<langsyntaxhighlight lang=tcl>package require Tcl 8.5
package require http
package require json
Line 2,526 ⟶ 2,481:
findBareTags $task [getTaskContent $task]
}
printResults</langsyntaxhighlight>
 
=={{header|Wren}}==
Line 2,535 ⟶ 2,490:
{{libheader|Wren-fmt}}
Uses Go's example files.
<langsyntaxhighlight ecmascriptlang=wren>import "./ioutil" for FileUtil
import "./pattern" for Pattern
import "./set" for Set
import "./sort" for Sort
import "./fmt" for Fmt
 
var p = Pattern.new("/=/={{header/|[+0/y]}}/=/=", Pattern.start)
Line 2,574 ⟶ 2,529:
Sort.insertion(names)
Fmt.print(" $2d in $-11s $n", count, lang, names)
}</langsyntaxhighlight>
 
{{out}}
Line 2,587 ⟶ 2,542:
{{trans|Ruby}}
Uses shared library cURL.
<langsyntaxhighlight lang=zkl>var [const] CURL=Import("zklCurl"),
partURI="http://rosettacode.org/wiki?action=raw&title=%s",
langRE=RegExp(0'!\s*==\s*{{\s*header\s*\|(.+)}}!), // == {{ header | zkl }}
Line 2,614 ⟶ 2,569:
tasks:=results[lang];
println("%d in %s: %s".fmt(tasks.len(),lang,tasks.concat(",")));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,631 ⟶ 2,586:
1 in ooRexx: Greatest_element_of_a_list
2 in uBasic/4tH: Greatest_common_divisor,Greatest_element_of_a_list
2 in МК??-61/52: Greatest_element_of_a_list,Greatest_element_of_a_list
</pre>
 
9,482

edits