babu_babu_babooのごみ箱

2018-02-01

波形インデントの投稿から、分割された回答を連結・整形して取り出し易いようにする

| 03:27

そのブックマークレットなるものを作った

教えてgooの回答に波形インデントをつけるのは、迷惑な話だろう。

そこで簡単テキストを取り出し易いように考えた。


まず、回答がされているタグ要素は、<div class="a_text">...</div>に囲まれている

連続した半角空白は、表示される段階で1文字分の隙間として表示される

なので、波形インデントを行の先頭に配置し、続いて半角空白のインデント、そしてテキストの構成にする

連続の回答の投稿のタイムラグで他の投稿があるかもしれない。投稿の並び替えも考慮しなければならない。

テキストを抽出するために回答文書の先頭は以下の用にする

    • // で始まり
    • @name 必要であれば名前
    • :文書番号

例:回答の始まりはこのような行で行う

//@babu_babu_baboo:1
...

例:

<div class="a_text">
//:1
一つの文章に
</div>

<div class="a_text">
//@pipi:1
abcdefg
</div>

<div class="a_text">
//@pipi:3
opqrstuv
</div>

<div class="a_text">
//@pipi:2
hijklmn
</div>

<div class="a_text">
//:3
正常である
</div>

<div class="a_text">
//:2
構成されて
</div>


取り出すプログラムは以下

<script>
javascript: (function() {
  let r = /^\s*\/\/(?:@(\D.*))?(?::(\d+))/;
  document.addEventListener('click', function(e) {
    let
      t = e.target,
      u = r.exec (t.textContent),
      v, d, n;

    if (t.className == 'a_text' && u) {
        [,n] = u;
        d = Array.from(t.ownerDocument.querySelectorAll('div.a_text'))
                .map(t => t.textContent)
                .filter (t =>
                  (u = r.exec (t))
                  ? u[1] == n
                    ? 1
                    : 0
                  : 0
                )
                .sort ((A,B)=>{
                  let [,,a] = r.exec (A), [,,b]= r.exec(B);
                  return a > b;
                })
               .join ('');
        alert(d);
    }
  }, false)
})()

</script>

これをショートコーディングする

<script>
javascript: ((l = /^\s*\/\/(?:@(\D.*))?(?::(\d+))/, I = 'a_text',c, o,O='textContent') =>
  document.addEventListener ('click',
     ({target:_}) => {
      _.className == I && (c = l.exec (_[O])) &&
        alert(
          Array.from(_.ownerDocument.querySelectorAll('div.' + I))
               .map(_ => _[O])
               .filter (_ => (o = l.exec (_)) && o[1] == c[1])
               .sort ((e,_) => l.exec (e) > l.exec(_))
               .join ('')
        )
  }, !1)
)()

更に極限まで(?)圧縮する

javascript:((l=/^\s*\/\/(?:@(\D.*))?(?::(\d+))/,I='a_text',c,o,O='textContent')=>document.addEventListener('click',({target:_})=>{_.className==I&&(c=l.exec(_[O]))&&alert(Array.from(_.ownerDocument.querySelectorAll('div.'+I)).map(_=>_[O]).filter(_=>(o=l.exec(_))&&o[1]==c[1]).sort((e,_)=>l.exec(e)>l.exec(_)).join(''))},!1)

これでブックマークレットの完成!


早く試してぇ〜


OKWave 用はこちら

javascript:((l=/^\s*\/\/(?:@(\D.*))?(?::(\d+))/,I='a_textarea',c,o,O='textContent')=>document.addEventListener('click',({target:_})=>{_.className==I&&(c=l.exec(_[O]))&&alert(Array.from(_.ownerDocument.querySelectorAll('div.'+I)).map(_=>_[O]).filter(_=>(o=l.exec(_))&&o[1]==c[1]).sort((e,_)=>l.exec(e)>l.exec(_)).join(''))},!1)

FujillinFujillin 2018/02/05 09:55 おはよ

>便利でしょうかね?
う〜〜ん。 おらはつかわねだ。

あのくらいの長さなら、とりあえずコピペして、全角空白を半角または無しに置換してテストしちゃう。
内容を見たいときは、読みながら適当に自分でインデント。
もっと長くなると(3倍くらいかな?)ちょっと面倒になってくる気もするけれど、そんときは、整形サービスがウェブ上にあったと思うので、そっちを利用しちゃうだろな。


話は画像の続きになるけれど、Google Mapなどでアイコンがデフォルトのままだとちょっと面白くないときがよくあります。
普通のサイトなら画像を置いとけばすんじゃうけれど、あそこの投稿の場合にはそうはいかない。
んでも、base64方式だと文字数がぁぁ・・・ってな時に見つけたのがGoogleのDynamic Iconsでした。

デフォルトマーカの色違いを作成してみたり、数字を入れて順番にしてみたり…
「メンテしないよ!」とはなっているが、ミニピクトグラムもあったりして、投稿時にはちょっと便利なのでした。
https://developers.google.com/chart/image/docs/gallery/dynamic_icons

babu_babu_baboobabu_babu_baboo 2018/02/05 15:10 おばんです

徹夜がたたったのか、深夜の本業がたたっのか体調がおもわしくなく、仕事も忙しくなりはめました。
src = base64... その辺をファイル画像にすると使えるのですが...

例のそのちょこっと管理しているページ。実は火葬場のWEBぺーじなので、派手なアイコンを使いたくても使えない。
普通のアイコンがジャンプしているだけで喜ばれるのです。

2018-01-31

Google Map にマーカーを付けてみた

| 03:40

100均ダイソー店舗情報のようなマップを作りたい その方法について
https://oshiete.goo.ne.jp/qa/10253056.html

この程度の回答で文字制限に引っかかるとは!

click イベントをマーカーに貼り付けようと思って

m.addEventListener ('click', ....

ここでエラーがでて、いきづまってしまった。

よく見たら

m.addListener (...

だった。


もしかしてだけど、アニメーション的なのが要望だったのか?


<!DOCTYPE html>
<html lang="ja">
<title>Google Maps APIテスト</title>
<meta charset="utf-8">
<style type="text/css">
#container {
	width: 1000px;
	margin: 0 auto;
}
#sample {
	width: 1000px;
	height: 800px;
}
</style>

<body>
<div id="container">
	<div id="sample"></div>
</div>


<script src="https://maps.googleapis.com/maps/api/js?key="></script>
<script>

{ //GoogleMap
    
  const
    tool = google.maps,

    createHtml = (n, t) =>
      '<div class="sample">' + n + '<br>' + t + '</div>',
    
    createMap = (target, latlng, zoom) =>
      new tool.Map (target, { center: new tool.LatLng (latlng), zoom }),
    
    createMark = (map, markers) =>
      markers.map (([lat, lng, name, text, url]) => {
        let
          p = new P (lat, lng),
          m = new tool.Marker ({ position: new tool.LatLng (p), map}),
          f = new tool.InfoWindow ({ content: createHtml (name, text)});

        if (url)
          m.setOptions ({ icon: { url }});

          m.addListener ('click', f.open.bind (f, map, m), false);
        return m;
      });
  

  class P { //position
    constructor (lat, lng) {
      this.lat = lat;
      this.lng = lng;
    }
  }
    
  
 
  class GoogleMap {
    constructor (target, [lat, lng], zoom = 15, markers = []) {
      if (3 > arguments.length)
        throw new Error (alert ('引数が不足'));

      this.target = target;
      this.position = new P (lat, lng);
      this.map  = createMap (target, this.position, zoom);
      this.mark = createMark (this.map, markers);
    }    
  }
  
  this.GoogleMap = GoogleMap;
}




let src = [
  "data:image/png;base64,",
  "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"
].join ('\n');

let
  target   = document.querySelector ('#sample'),
  position = [35.679000, 139.780000],
  zoom     = 13,
  markers  = [
    [35.710001, 139.810666, '東京スカイツリー', '高さ634m'],
    [35.658641, 139.745473, '東京タワー', '高さ333m', src]
  ],
  map = new GoogleMap (target, position, zoom, markers);

</script>

アニメーションを付加してみる

<!DOCTYPE html>
<html lang="ja">
<title>Google Maps APIテスト</title>
<meta charset="utf-8">
<style type="text/css">
#sample {
	width: 1000px;
	height: 800px;
}
</style>

<body>
<div id="sample"></div>


<script src=
  "https://maps.googleapis.com/maps/api/js?key="
></script>
<script>

{ //GoogleMap

  const
    tool = google.maps,

    createHtml = (n, t) =>
      '<div class="sample">' + n + '<br>' + t + '</div>',

    createMap = (target, latlng, zoom) =>
      new tool.Map (target, { center: latlng, zoom }),

    createMarker = markers =>
      markers.map (([lat, lng, title, text, icon], i) =>
        new tool.Marker ({
          title,
          //label: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i],
          position: new P (lat, lng),
          animation: tool.Animation.DROP,
          //draggable:true,
          icon
        })),

    createInfoWin = markers =>
      markers.map (([lat, lng, title, text, icon]) =>
        new tool.InfoWindow ({ content: createHtml (title, text)})),

    addClickEvent = (map, marker, infoWin) =>
      marker.forEach ((m, i) =>
        m.addListener ('click', infoWin[i].open.bind (infoWin[i],map, m))
      );



  class P { //position
    constructor (lat, lng) {
      this.lat = lat;
      this.lng = lng;
    }
  }



  class GoogleMap {
    constructor (target, [lat, lng], zoom = 15, markers = []) {
      if (3 > arguments.length)
        throw new Error (alert ('引数が不足'));

      this.target = target;
      this.map = createMap (target, new P (lat, lng), zoom);
      this.marker = createMarker (markers);
      this.infoWin = createInfoWin (markers);

      this.addClickInfo ();

      setTimeout (this.setMark.bind (this), 1500);
      setTimeout (this.setAnimeBounce.bind (this), 3500);
    }

    setMark (wait = 2000) {// ms秒かけてマーカーの全てを表示する
      let interval = 2000 / (this.marker.length || 1);
      this.marker.forEach ((m, i) =>
        setTimeout (m.setMap.bind (m, this.map), interval * i));
    }

    setAnimeBounce () {
      this.marker.forEach (m =>
        m.setAnimation (tool.Animation.BOUNCE));
    }

    removeMark (wait = 0) {
      let interval = 2000 / (this.marker.length || 1);
      this.marker.forEach ((m, i) =>
        setTimeout (m.setMap.bind (m, null), interval * i));
    }

    addClickInfo () {
      addClickEvent (this.map, this.marker, this.infoWin);
    }
  }

  this.GoogleMap = GoogleMap;
}



let
  target   = document.querySelector ('#sample'),
  position = [35.679000, 139.780000],
  zoom     = 13,
  markers  = [
    [35.710001, 139.810666, '東京スカイツリー', '高さ634m'],
    [35.658641, 139.745473, '東京タワー', '高さ333m']
  ];

new GoogleMap (target, position, zoom, markers);

</script>

FujillinFujillin 2018/02/01 09:50 おはよっす!

またまた、長いのを真夜中に・・・
画像に凝ったりするから、長いんじゃーっ! (笑)


そういえば、以前、base64方式ではない方法を思いついて、最初の回答で画像を添付しておいて、二回目以降の投稿でその画像を利用するという、自分的には良いアイデアだと思って実行したことがあるのですが・・・

なんとっ!
予告しておいたにも拘わらず、最初の投稿のところで締め切られてしまい、肝心な、それを利用したソースは日の目を見ずということがありました。(悲)
https://oshiete.goo.ne.jp/qa/Q9764465.html

CSSアニメーションの練習用にさせてもらっていたのだけれど、画像自体は少々手抜きだったものの、結果としては結構いい感じになったと思うのだけれど、お蔵入りになっちゃいました。
中途半端によく見えない、幽霊のような画像だけが宙に浮いてしまいました。(背景色がないとね…)

babu_babu_baboobabu_babu_baboo 2018/02/01 18:52 おばんです。

さすがに連チャンの徹夜(?)は辛いです。
ちょっとだけですが私が管理しているホームページに、GoogleMap でマーカーのついたページを実現させたくて無理してしまいました。
オブジェクト指向的なプログラムを目標としてコードを書いていますが、出回っているサンプルがグローバル変数をガンガン使うものばかりで、見直して習得するまでに時間がかかってしまいます。
--
「画像をアップしておいて直リンクを使用する」う〜ん。そんなこと可能だったのか... 使えるかも(笑)

--
今どきの人は、強く言い出すと凹む奴らばかりなのでしょうか?
もう何のレスもない!それはそれでよいのだけれど。
今どきはインスタ栄(ばえ)ならぬ、玄人栄(ばえ)けする投稿っすよ!

babu_babu_baboobabu_babu_baboo 2018/02/01 21:13 javascript:(function(){document.addEventListener('click',function(e){let t=e.target;if(t.className=='a_text')alert(t.textContent.replace(/^(\s| )*|(\s| )*$/gm,''))},false)})()

教えてgoo用のブックマークレットを作ってみました。波インデントの余白を取り除いてコードを取り出しやすくします。
便利でしょうかね?
ご存知だと思いますが、上のコードを選択してブラウザのブックマークバーにドラッグ&ドロップします
教えてgooのページを開いたら、登録したブックマークレットを実行します。
解答欄のテキスト上でクリックするとアラートに文字が表示されます

babu_babu_baboobabu_babu_baboo 2018/02/01 21:14 こっちだす
javascript:(function(){document.addEventListener('click',function(e){let t=e.target;if(t.className=='a_text')alert(t.textContent.replace(/^(\s| )*|(\s| )*$/gm,''))},false)})()

babu_babu_baboobabu_babu_baboo 2018/02/02 04:32 新しく書き直しました
http://d.hatena.ne.jp/babu_babu_baboo/20180201/1517509653

FujillinFujillin 2018/02/05 18:03 お蔵いりしてたやつを引っ張りだしてみた。

とりあえず動作するレベル。
border-radiusの使えるブラウザ対象なのだ。

<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>

<style type="text/css">
body { background-color: #000; }
#wrapBox {
width: 300px; height: 300px;
border-radius: 150px;
position:relative; overflow: hidden;
margin: 50px auto;
background-color: #002;
}

#thunderMask{
width:100%; height:100%;
background-color: #FFF;
position:absolute; opacity: 0;
}

.thunder1 { animation: lightning1 0.12s; }
.thunder2 { animation: lightning2 0.04s; }
@keyframes lightning1{
0% { opacity: 0; }
30% { opacity:0.3; }
60% { opacity: 0; }
70% { opacity: 0.1; }
100% { opacity: 0.5; }
}
@keyframes lightning2{
0% { opacity: 0; }
60% { opacity: 0.1; }
100% { opacity:0.2; }
}

#images { position:absolute; list-style-type: none; }
#images li{
position: absolute;
top: 0; left:0;
width: 300px; height:300px;
}
#images li div{
height: 10px; overflow: hidden;
transition: height 0.1s 0.05s;
}
#images li.active div{ height: 300px; }
#images img{ position:relative; width: 450px; height: 450px; }

</style>
</head>
<body>

<input type="button" value="stop" onclick="stop()" />
<div id="wrapBox">
<ul id="images"></ul>
<div id="thunderMask"></div>
</div>

<script>
var stop = (function(){
// var imageURL = "./img/thunder.png";

// ANo1で投稿した画像のURL
var imageURL = "http" + "s://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/0/587726_5923f06b0fc11/M.png";

function r(n){ return Math.floor(Math.random() * n); }

// 一瞬光る効果
function lightning(){
var e = document.querySelector("#thunderMask");
var cname = r(10)>6?"thunder1":"thunder2";
e.classList.remove("thunder1");
e.classList.remove("thunder2");
setTimeout(function(){e.classList.add(cname);}, 20);
}

// ゆっくり消える
function fadeOut(elm){
var duration = r(50) + 30, op = 1;
var intervalId = setInterval(function(){
op -= 0.01;
if(op>0) {
elm.style.opacity = op;
} else {
clearInterval(intervalId);
elm.parentNode.removeChild(elm);
}
}, duration);
}

// 新しい位置で画像を追加
function addImage(){
var img = document.createElement("img");
var li = document.createElement("li");
var div = document.createElement("div");
img.src = imageURL;
img.style.top = r(-150) + "px";
img.style.left = r(-150) + "px";

div.appendChild(img);
li.appendChild(div);
// var tf = "translate(" + (r(90)-50) + "px) rotate(" + r(360) + "deg)";

var tf = "rotate(" + r(360) + "deg)";
if(r(10)>5) tf += " rotateY(180deg)";
li.style.transform = tf;

lightning();
document.getElementById("images").appendChild(li);
setTimeout( function(){ li.classList.add("active"); }, 20);
fadeOut(li);
}

// 繰り返しを制御
var flag = true;
function controller(){
var next = r(2500) + 500;
addImage();
if(flag) setTimeout(controller, next);
}

controller();
return function(){ flag = false; }
})();
</script>
</body>
</html>

2018-01-30

IndexedDB をなぞってみる

| 05:01

JavaScriptの修正を助けて下さい
https://oshiete.goo.ne.jp/qa/10251931.html

なぜ Firefox で動かない! Help me!!


いつも質問者への回答は、ちゃぶ台をひっくり返したように例題を無視して一から書きたくなる性分なのだが、今回は質問者のプログラムを修正する形で書いてみた。こういうアレンジだとコードを読むのが楽だと思う。

Ajaxを使って裏でデータを読みまくりデータベースを構築するのも良いのではないか?ともおもったが、ページが遷移してしまうと無駄になりそう。つぎにレスが付いたら、いよいよ波インデントだ!


<!DOCTYPE html>
<html lang="ja">
<meta charset="UTF-8">
<title>IndexedDB test</title>
<style>
body {
  background-image: linear-gradient(-90deg, #495B4B, #FFFFFF);
}

h1, h2, h3, h4, h5, h6, th {
  font-weight: normal;
}


body {
  counter-reset : no 0;
}

fieldset {
  box-shadow: 3px 3px 8px rgba(0,0,0,.6);
  border: 2px silver solid;
  border-radius: 8px;
  margin-bottom: 1em;
}

legend, table {
  color: #343;
  text-shadow: -1px -1px 0px white, 1px 1px 2px black;
}

legend:before {
  counter-increment : no 1;
  content           : "[" counter(no, upper-latin) "]";
  padding-right     : 1ex;
}

</style>

<body>
<fieldset>
  <legend>Input</legend>
  <table>
    <tr>
      <th>バリュー1値
      <td><input id="todovalue" name="todovalue" type="text">
    <tr>
      <th>キー値
      <td><input type="text" id="todoItem" name="todo">
          <input type="button" id="btnAddTodo" value="追加">
  </table>

  <h4>追加結果表示</h4>
  <ul id="todoItems">
  </ul>
</fieldset>


<fieldset>
  <legend>Serach</legend>
  キー値の入力<input type="text" id="selectkey">
  <input type="button" value="検索" id="btngetValue">
</fieldset>


<fieldset>
  <legend>Result</legend>
  <div id="result"></div>
</fieldset>



<script>
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.msIndexedDB || window.webkitIndexedDB;

const
  DATA_BASE_NAME   = 'todoList',
  TRANSACTION_NAME = 'todo';


if (indexedDB)
  var app = { indexedDB: {db: null} };
else
  throw new Error (alert ("IndexedDBが使えません"));


app.indexedDB.open =
  function () {
    let openRequest = indexedDB.open (DATA_BASE_NAME);

    openRequest.onupgradeneeded = function ({target}) {
      (app.indexedDB = target.result)
        .createObjectStore (TRANSACTION_NAME, { keyPath: 'key' })
        .createIndex ('val', 'val', { unique: false });
      
      target.transaction.oncomplete = function () {
        app.indexedDB.getAllTodoItems();
      };
    };

    openRequest.onsuccess = function ({target: { result }}) {
      app.indexedDB.db = result;
      app.indexedDB.getAllTodoItems ();
    };

    openRequest.onerror = function (e) {
      console.log ('Database error: ' + e.target.error);
    };
  };



app.indexedDB.deleteDB =
  function () {
    indexedDB.deleteDatabase (DATA_BASE_NAME);
  };



app.indexedDB.getAllTodoItems =
  function () {
    let doc = document;
   
    doc.querySelector ('#todoItems').textContent =
    doc.querySelector ('#todoItem').value =
    doc.querySelector ('#todovalue').value = '';

    app.indexedDB.db
       .transaction (TRANSACTION_NAME, 'readonly')
       .objectStore (TRANSACTION_NAME)
       .openCursor ()
       .onsuccess =
         function ({target: { result }}) {
           if (result) {
             renderTodo (result.value);
             result.continue ();
           }
         };

    function renderTodo ({ key, val }) {
      let
        doc = document,
        items = doc.querySelector ('#todoItems'),
        li = doc.createElement ('li'),
        a = doc.createElement ('a');
      
      li.textContent = key + ' = ' + val;
      a.textContent ='[ 削除 ]';
      a.href = '#key=' + key;
      a.className = 'btnDeleteTodo';
      
      items.appendChild (li).appendChild (a);
    }
  };



app.indexedDB.addTodo =
  function () {
    let
      doc = document,
      key = doc.querySelector ('#todoItem').value,
      val = doc.querySelector ('#todovalue').value;

    if ('' !== key) {
      let request = app.indexedDB.db
                       .transaction ([TRANSACTION_NAME], 'readwrite')
                       .objectStore (TRANSACTION_NAME)
                       .add ({ key, val });

      request.onsuccess = function (_) { app.indexedDB.getAllTodoItems (); };
      request.onerror   = function (event) { console.log ('Error Adding: ', event); };
    }
  };



app.indexedDB.getValue =
  function (_){
    app.indexedDB.db
       .transaction ([TRANSACTION_NAME])
       .objectStore (TRANSACTION_NAME)
       .get (document.querySelector ('#selectkey').value)
       .onsuccess = 
         function ({target: { result }}) {
           document.querySelector ('#result').textContent = result
           ? 'key:' + result.key + ' value:' + result.val
           : '指定したキーは存在しません。';
         };
  };



app.indexedDB.handleEvent =
  function ({ target }) {
    switch (target.id) {
    case 'btnAddTodo' : return app.indexedDB.addTodo ();
    case 'btngetValue' : return app.indexedDB.getValue ();
    }
    switch (target.className) {
    case 'btnDeleteTodo' :
      
      break;
    }
  };

//_________________________
init:
document.addEventListener ('click', app.indexedDB, false);
app.indexedDB.open();

</script>

FujillinFujillin 2018/01/31 09:38 おはよー!

寝る前にこんな質問が出てるなと思って、朝起きてみたらいっぱい回答が・・・
活動時間がすんごいですね。

質問が長いので、今回のものはよく見ていませんが、実は、この方は同じような質問を以前にしていました。
https://oshiete.goo.ne.jp/qa/10131683.html

その時に提示されたスクリプトもタイポがいろいろあったので、質問の状態(ある程度動作する状態)にするまでにひと作業しなければならなかった。
具体的に細かくは、いちいち言わなかったけれど指摘しといたし、プレフィックス付きのIDBFactoryオブジェクトを変数に入れているのに、その後でまだプレフィックス付きで直接記述していたり・・・
質問している検索の方法と表示の際の問題点も指摘しといたのに忘れてんのかなぁ・・・

他の問題にぶつかったときのために、IDB APIの仕様書のアドレスまで紹介しといたんだけどね・・・

babu_babu_baboobabu_babu_baboo 2018/01/31 18:28 こんばんは。

プログラム書いていて気づいたら朝の4時頃。
やべぇ〜!と思って横になりましたが、目が覚めたのが10時。
2日連続休日じゃなければ、できない芸当ですね。
ゆっくりとした時間を過ごしました。

仕事を便利にするツールとしてのJavaScriptのプログラムを書いていますが、そっちを先にやれよ!と。

2018-01-29

テキストのインデントを波打つように整形する

| 02:06

テキストのインデントを波打つように整形する

教えてgoo に投稿するために、わざわざ書いてみた

あれ?空白行の処理が変?あとで直そう!

<!DOCTYPE html>
<meta charset="utf-8">
 <title>インデントを波の様にする</title>
 <style>
  body {
   background-image: linear-gradient(-90deg, #495B4B, #FFFFFF);
    }
     
      h1, h2, h3, h4, h5, h6, th {
       font-weight: normal;
        }
         
         h1 { font-size: x-large; }
          
          form {
          counter-reset : no 0;
          }
          
         fieldset {
         box-shadow: 3px 3px 8px rgba(0,0,0,.6);
        border: 2px silver solid;
       border-radius: 8px;
      margin-bottom: 1em;
     }
    
   form legend, table {
  color: #343;
 text-shadow: -1px -1px 0px white, 1px 1px 2px black;
 }

form legend:before {
counter-increment : no 1;
 content           : "[" counter(no) "]";
 padding-right     : 1ex;
  }
   
    textarea {
     box-sizing        : border-box;
      width : 100%;
       border-style: none;
        background: transparent;
         color: #444;
         font-size: x-small;
          }
          
          input:checked+span {
          border-bottom: 2px #454 solid;
          }
         
         img {
        border: 2px red solid;
       height: 100px; width: 100px;
      }
     
    
   </style>
  
 <body>
 <h1>テキストのインデントを波の様に整形する</h1>
<form>
<fieldset>
<legend>Texts</legend>
 <textarea cols="90" rows="12" placeholder="ここにテキストをドロップ or ペーストします"></textarea>
 </fieldset>
  
   <fieldset>
    <legend>Setting</legend>
     <table>
      <tr>
       <th>形状
        <td>
         <label>
         <input type="radio" name="type" value="cos" checked>
          <span>Cos波</span>
          </label>
          
          <tr>
          <th>インデント
         <td>
         <input name="indent" type="number" min="0" max="50" value="0">(単位:半角文字)
        
       <tr>
      <th>振幅
     <td>
    <input name="sinpuku" type="number" min="0" max="50" value="16">(単位:半角文字)
   
  <tr>
 <th>周期
 <td>
<input name="shuuki" type="number" min="0" max="50" value="32">(単位:行)

<tr>
 <th>コメント
 <td>
  <label>
   <input type="checkbox" name="fm1" value="1">
    <span>/*以降から*/までを取り除く</span>
     </label><br>
      
       <label>
        <input type="checkbox" name="fm2" value="1">
         <span>//以降の文字を取り除く</span>
         </label><br>
          
          <label>
          <input type="checkbox" name="fm3" value="1">
          <span>#以降の文字を取り除く</span>
          </label>
         
         <tr>
        <th>空白文字
       <td>
      <label>
     <input type="checkbox" name="fm4" value="1" checked>
    <span>前後の空白文字(全角も含む)削除する</span>
   </label><br>
  
 <tr>
 <th>空白行
<td>
<label>
<input type="checkbox" name="fm0" value="1">
 <span>削除する</span>
 </label><br>
  
   <tr>
    <th>インデント文字
     <td>
      <label>
       <input type="checkbox" name="ch1" value="1">
        <span>半角空白文字(2個)を全角空白にする</span>
         </label>
         
          </table>
          <input type="button" value="整形する" onclick="go()">
          </fieldset>
          
          <fieldset>
         <legend>Result</legend>
         <textarea cols="90" rows="36" placeholder="ここに結果が表示されます"
        onfocus=""></textarea>
       </fieldset>
      </form>
     
    <script>
   
  function go () {
 let
 doc = document,
tarea = doc.querySelectorAll ('form textarea'),
text= tarea[0].value,
indent = parseInt (doc.querySelector ('input[name="indent"]').value, 10),
 sinpuku = parseInt (doc.querySelector ('input[name="sinpuku"]').value, 10),
 shuuki = parseInt (doc.querySelector ('input[name="shuuki"]').value, 10),
  e;
   
    if (e = doc.querySelector ('input[name="fm1"]:checked'))
     text = text.replace (/\/\*([^*]|\*[^\/])*\*\//gm, '');
      if (e = doc.querySelector ('input[name="fm2"]:checked'))
       text = text.replace (/\/\/.*/gm, '');
        if (e = doc.querySelector ('input[name="fm3"]:checked'))
         text = text.replace (/#.*/gm, '');
         if (e = doc.querySelector ('input[name="fm4"]:checked'))
          text = text.replace (/(^( | )*|( | )*$)/gm, '');
          
          if (e = doc.querySelector ('input[name="fm0"]:checked'))
          text = text.replace (/^( | )*/gm, '').replace (/^(\r\n|\r|\n)/gm, '');
          
         
         
        let
       line = text.split (/\n\r|\n|\r/g),
      i = 0,
     I = line.length,
    sp = ' '.repeat (indent),
   pi2 = Math.PI * 2,
  offset = 0,
 spall;
 
for (;i < I; i++) {
switch (doc.querySelector ('input[name="type"]:checked').value) {
case 'cos' :
 offset = Math.floor((1 - Math.cos (pi2 / shuuki * i)) * sinpuku * .5 + .5);
 break;
  default :
   offset = 0;
    break;
     }
      spall = sp + (' '.repeat (offset));
       if (e = doc.querySelector ('input[name="ch1"]:checked'))
        spall = spall.replace (/  /g,' ');
         line[i] = spall + line[i];
         }
          
          text = line.join ('\n');
          
          tarea[1].value = text;
          }
         </script>
         

FujillinFujillin 2018/01/30 11:10 また来ました。

掲示板を先にみたので、第一印象は『インデント? なんか見かけない感じやな…』
・・って、中を見てみたら『あれっ?! 文書構造と全然関係ないやんっ‼ 』
・・・ただの、波型模様だったのね。遊んでますな〜(笑)


しっかし、今頃になってPHPが登場しちゃうとはね。
これまでは、そんな存在は一切匂いもしなかったのに。

何に使っているのかは不明ですが、サーバ側でもプログラムを使えるのなら、方法はなんでもありと思うので、ひたすらLocalStrageにこだわる理由もなさそうに思うのですが…(こないだはCookieをお勧めしといたんだけどな)

PHP使ってるのなら(まさかhtml出力だけじゃないだろうから)、何らかのプログラムになっていると思うのだけれど、その割にはプログラム的な思考がさっぱり感じられない・・・
ちなみに、おらの環境はサーバもどきは使えるのだけれどPHPとか使えないので、サーバ側のプログラムはまったく知らないのだ(汗)

babu_babu_baboobabu_babu_baboo 2018/01/30 16:06 こんにちは!

心の中で決めました。2回め以降の怪答には、波インデントを盛り込もうと・・・
あちらの使っている環境には、データベースもあるようなので、つまるところ
返答は非常に丁寧なのですが、ほぼこぴぺで使えるようなサンプルが欲しいのでしょう。
いつものことですね。

私のパソコンはPHPも動くので、ネットさえ検索できる環境にあればそこそこ使えます。
がっ!しかし「phpのバッファリングを使って、このページを保存する」というのが
なんの目的で使用しなければならないのか、まったく理解できません。

FujillinFujillin 2018/01/30 16:57 さらに回答がつけられていたので、また覗きに来た。


>2回め以降の怪答には、波インデントを〜
無駄に文字数使っちゃうね。
とは言え、投稿可能な文字数が増えたので、以前のように簡単に溢れることはなくなったから、よほど長い回答をしない限りは大丈夫かな(笑)

>ほぼこぴぺで使えるようなサンプルが欲しいのでしょう
そんな気はしますが、その割には情報の出し方がイマイチ。
なんかのパーツをはめ込めば、オールマイティで動作すると思っているかのようです。
それって、仮に、ほぼ実現できたとしても、メッチャ長い、一大プログラムを要求することになる可能性が大なのだが…

>phpのバッファリングを使って、このページを保存する
PHP用語は知らんけど、出力用のバッファとかの意味かなぁ?(ほかに思いつかん)
だとすると、どう使ってどう保存するのかまったく想像がつかない。
言葉は無視して雰囲気でとらえるなら、「サーバ側にデータを保存する」ってことのようにも思えるけれど、それならもはやLocalStorageとかは関係なくなってるはずなのだが…

一瞬、質問の文章通りのシンプルなものを作って回答しようかと思ったけれど、嫌味になるのでやめといた。

2018-01-27

久々に回答してみた

| 23:55

プログラムを書くより、登録しておいたIDとPasswordを忘れたために、

プログラムを書くぐらい手間取ってしまった。


久々に正規表現のオプションに'g'を使った。

RC形式での重複や文字数制限等は無視した。

var と let の混在に疑問符がつくね。


投稿してから気づいた、RC形式なのに相対指定ができないのだからだめじゃねぇか!

'$' でも書式に組み込むとか?



https://oshiete.goo.ne.jp/qa/10241635.html


--

本年1月18日をもって、専務理事から理事長スライド昇格したが、前理事長の所有していた現金のありかがわからない。

どうすんべ。

FujillinFujillin 2018/01/29 14:15 久々に来てみました。

>あの人が食いつく前に
それは、もしかしておいらのことかな?

おいらはまだ同じところをうろうろしているけれど、babuさんはもうずっと霞の向こうまでいっちゃってるので、食いつきようがないですね。

まぁ、そもそもあの仕組み全体がどうもよくわからないのですよね。
「問題群の目次的なページがあって、そこに終わったかどうかを表示したい」ってんだろうけれど、なんで自己申告なの?
そのうえ、hash利用じゃ何でもできちゃう・・・って、どうせ自己申告だからどうでもいのかも知れないけど。

どうせなら、個々の問題の回答の正誤を記録して、全部できていれば自動的に終了とかでいいんじゃね?
そうすりゃ、各問題のページに行っても、終わった問題とそうでないものの表示を変えることも可能だし・・・
目次ページの表示も、終了/未了だけでなく、何パーセントまで終わったかをセルの色で表示するならインジケータ的に表示するとか、いろいろ考えられそうな気がするし・・・
また、最近風に考えれば、わざわざページ転々と変えなくても、同一ページ内で処理しちゃってもよさそうな気もするし・・・

・・・等々の謎が多いのでした。


※ なんだかわからないけど、「理事長」に就任なさったそうで、おめでとうございます。
  (身に覚えのない責任だけを取らされたりするこのないように・・)

babu_babu_baboobabu_babu_baboo 2018/01/30 00:47 Fujillin さん、
おはようございます。おひさしぶりです。

そう!あなたのことです。

>霞の向こうまで
とんでもない!霧の中、同じところをぐるぐるしてるのが恥ずかしく
本業に専念していましたよ。

>・・・等々の謎が多いのでした。
私も同じことを妄想してました

また新たに質問がされていて「PHPでバッファリング」なんて言葉が出てきました。
ちょっと私が無視されるまで、回答に付き合ってみようかな?

>身に覚えのない責任だけを取らされたりする
すでにですね、責任問題になりかねない事案が発生しました。
「死人に口無し」なので現金の所在がわからないとか、
前理事長の奥様のグループ会社が奥様を切ろうとしているので、助けて〜だとか、
私の人生も小説に書けそうなくらいなのに、あちらは大河ドラマになれそうなシナリオがわんさか。
そもそも私は、部外者なのに・・・

詳しく書けないのが辛い。www